1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2024-12-02 09:21:40 +02:00
lazygit/files_panel.go

194 lines
4.5 KiB
Go
Raw Normal View History

2018-05-26 05:23:39 +02:00
package main
import (
// "io"
// "io/ioutil"
// "strings"
2018-06-01 15:23:31 +02:00
"errors"
2018-05-26 05:23:39 +02:00
"strings"
"github.com/fatih/color"
2018-06-05 10:47:31 +02:00
"github.com/jesseduffield/gocui"
2018-05-26 05:23:39 +02:00
)
2018-06-01 15:23:31 +02:00
var (
// ErrNoFiles : when there are no modified files in the repo
ErrNoFiles = errors.New("No changed files")
)
2018-05-26 05:23:39 +02:00
func stagedFiles(files []GitFile) []GitFile {
result := make([]GitFile, 0)
for _, file := range files {
if file.HasStagedChanges {
result = append(result, file)
}
}
return result
}
func handleFilePress(g *gocui.Gui, v *gocui.View) error {
2018-06-01 15:23:31 +02:00
file, err := getSelectedFile(v)
if err != nil {
return err
}
2018-05-26 05:23:39 +02:00
if file.HasUnstagedChanges {
stageFile(file.Name)
} else {
unStageFile(file.Name)
}
if err := refreshFiles(g); err != nil {
return err
}
if err := handleFileSelect(g, v); err != nil {
return err
}
return nil
}
2018-06-01 15:23:31 +02:00
func getSelectedFile(v *gocui.View) (GitFile, error) {
2018-05-26 05:23:39 +02:00
if len(state.GitFiles) == 0 {
2018-06-01 15:23:31 +02:00
return GitFile{}, ErrNoFiles
2018-05-26 05:23:39 +02:00
}
2018-06-01 15:23:31 +02:00
lineNumber := getItemPosition(v)
return state.GitFiles[lineNumber], nil
2018-05-26 05:23:39 +02:00
}
func handleFileRemove(g *gocui.Gui, v *gocui.View) error {
2018-06-01 15:23:31 +02:00
file, err := getSelectedFile(v)
if err != nil {
return err
}
2018-05-26 05:23:39 +02:00
var deleteVerb string
if file.Tracked {
deleteVerb = "checkout"
} else {
deleteVerb = "delete"
}
2018-05-27 08:32:09 +02:00
return createConfirmationPanel(g, v, strings.Title(deleteVerb)+" file", "Are you sure you want to "+deleteVerb+" "+file.Name+" (you will lose your changes)? (y/n)", func(g *gocui.Gui, v *gocui.View) error {
2018-05-26 05:23:39 +02:00
if err := removeFile(file); err != nil {
panic(err)
}
return refreshFiles(g)
}, nil)
}
2018-06-01 15:23:31 +02:00
func handleIgnoreFile(g *gocui.Gui, v *gocui.View) error {
file, err := getSelectedFile(v)
if err != nil {
return err
}
if file.Tracked {
return createErrorPanel(g, "Cannot ignore tracked files")
}
gitIgnore(file.Name)
return refreshFiles(g)
}
2018-05-26 05:23:39 +02:00
func handleFileSelect(g *gocui.Gui, v *gocui.View) error {
2018-06-01 15:23:31 +02:00
baseString := "tab: switch to branches, space: toggle staged, c: commit changes, o: open, s: open in sublime, i: ignore"
item, err := getSelectedFile(v)
if err != nil {
if err != ErrNoFiles {
return err
}
renderString(g, "main", "No changed files")
colorLog(color.FgRed, "error")
return renderString(g, "options", baseString)
}
2018-05-26 05:23:39 +02:00
var optionsString string
if item.Tracked {
2018-06-01 15:23:31 +02:00
optionsString = baseString + ", r: checkout"
2018-05-26 05:23:39 +02:00
} else {
2018-06-01 15:23:31 +02:00
optionsString = baseString + ", r: delete"
2018-05-26 05:23:39 +02:00
}
renderString(g, "options", optionsString)
diff := getDiff(item)
return renderString(g, "main", diff)
}
2018-06-01 15:23:31 +02:00
func genericFileOpen(g *gocui.Gui, v *gocui.View, open func(string) (string, error)) error {
file, err := getSelectedFile(v)
if err != nil {
return err
}
_, err = open(file.Name)
2018-05-26 05:23:39 +02:00
return err
}
2018-06-01 15:23:31 +02:00
func handleFileOpen(g *gocui.Gui, v *gocui.View) error {
return genericFileOpen(g, v, openFile)
}
2018-05-26 05:23:39 +02:00
func handleSublimeFileOpen(g *gocui.Gui, v *gocui.View) error {
2018-06-01 15:23:31 +02:00
return genericFileOpen(g, v, sublimeOpenFile)
2018-05-26 05:23:39 +02:00
}
func refreshFiles(g *gocui.Gui) error {
filesView, err := g.View("files")
if err != nil {
return err
}
// get files to stage
gitFiles := getGitStatusFiles()
state.GitFiles = mergeGitStatusFiles(state.GitFiles, gitFiles)
filesView.Clear()
red := color.New(color.FgRed)
green := color.New(color.FgGreen)
for _, gitFile := range state.GitFiles {
if !gitFile.Tracked {
red.Fprintln(filesView, gitFile.DisplayString)
continue
}
green.Fprint(filesView, gitFile.DisplayString[0:1])
red.Fprint(filesView, gitFile.DisplayString[1:3])
if gitFile.HasUnstagedChanges {
red.Fprintln(filesView, gitFile.Name)
} else {
green.Fprintln(filesView, gitFile.Name)
}
}
correctCursor(filesView)
handleFileSelect(g, filesView)
2018-05-26 05:23:39 +02:00
return nil
}
2018-05-26 07:44:44 +02:00
2018-05-27 08:32:09 +02:00
func pullFiles(g *gocui.Gui, v *gocui.View) error {
devLog("pulling...")
createSimpleConfirmationPanel(g, v, "", "Pulling...")
go func() {
if output, err := gitPull(); err != nil {
createSimpleConfirmationPanel(g, v, "Error", output)
} else {
closeConfirmationPrompt(g)
2018-06-01 15:23:31 +02:00
refreshCommits(g)
refreshFiles(g)
refreshStatus(g)
devLog("pulled.")
2018-05-27 08:32:09 +02:00
}
}()
2018-06-01 15:23:31 +02:00
return nil
2018-05-26 07:44:44 +02:00
}
2018-05-27 08:32:09 +02:00
func pushFiles(g *gocui.Gui, v *gocui.View) error {
devLog("pushing...")
createSimpleConfirmationPanel(g, v, "", "Pushing...")
go func() {
if output, err := gitPush(); err != nil {
createSimpleConfirmationPanel(g, v, "Error", output)
} else {
closeConfirmationPrompt(g)
2018-06-01 15:23:31 +02:00
refreshCommits(g)
refreshStatus(g)
devLog("pushed.")
2018-05-27 08:32:09 +02:00
}
}()
return nil
}