summaryrefslogtreecommitdiffstats
path: root/files_panel.go
diff options
context:
space:
mode:
authorJesse Duffield <jessedduffield@gmail.com>2018-07-21 16:06:38 +1000
committerJesse Duffield <jessedduffield@gmail.com>2018-07-21 16:06:38 +1000
commita47c889cbb385e93e895a257e12038a5827c45b8 (patch)
treeea05ee7849b9f6cfc9e699013b2a948ff3031566 /files_panel.go
parentbcdfe242ac4050c4be22fc43791f3b98952b2f73 (diff)
parent61dcbb456d42fefc8aaac456e02c40bdef7de774 (diff)
merge with develop
Diffstat (limited to 'files_panel.go')
-rw-r--r--files_panel.go424
1 files changed, 214 insertions, 210 deletions
diff --git a/files_panel.go b/files_panel.go
index cb15e8b3b..f29cbb75a 100644
--- a/files_panel.go
+++ b/files_panel.go
@@ -2,65 +2,65 @@ package main
import (
- // "io"
- // "io/ioutil"
+ // "io"
+ // "io/ioutil"
- // "strings"
+ // "strings"
- "errors"
- "strings"
+ "errors"
+ "strings"
- "github.com/fatih/color"
- "github.com/jesseduffield/gocui"
+ "github.com/fatih/color"
+ "github.com/jesseduffield/gocui"
)
var (
- // ErrNoFiles : when there are no modified files in the repo
- ErrNoFiles = errors.New("No changed files")
+ // ErrNoFiles : when there are no modified files in the repo
+ ErrNoFiles = errors.New("No changed files")
)
func stagedFiles(files []GitFile) []GitFile {
- result := make([]GitFile, 0)
- for _, file := range files {
- if file.HasStagedChanges {
- result = append(result, file)
- }
- }
- return result
+ 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 {
- file, err := getSelectedFile(g)
- if err != nil {
- return err
- }
+ file, err := getSelectedFile(g)
+ if err != nil {
+ return err
+ }
- if file.HasUnstagedChanges {
- stageFile(file.Name)
- } else {
- unStageFile(file.Name)
- }
+ if file.HasUnstagedChanges {
+ stageFile(file.Name)
+ } else {
+ unStageFile(file.Name, file.Tracked)
+ }
- if err := refreshFiles(g); err != nil {
- return err
- }
- if err := handleFileSelect(g, v); err != nil {
- return err
- }
+ if err := refreshFiles(g); err != nil {
+ return err
+ }
+ if err := handleFileSelect(g, v); err != nil {
+ return err
+ }
- return nil
+ return nil
}
func getSelectedFile(g *gocui.Gui) (GitFile, error) {
- if len(state.GitFiles) == 0 {
- return GitFile{}, ErrNoFiles
- }
- filesView, err := g.View("files")
- if err != nil {
- panic(err)
- }
- lineNumber := getItemPosition(filesView)
- return state.GitFiles[lineNumber], nil
+ if len(state.GitFiles) == 0 {
+ return GitFile{}, ErrNoFiles
+ }
+ filesView, err := g.View("files")
+ if err != nil {
+ panic(err)
+ }
+ lineNumber := getItemPosition(filesView)
+ return state.GitFiles[lineNumber], nil
}
func handleFileRemove(g *gocui.Gui, v *gocui.View) error {
@@ -83,93 +83,96 @@ func handleFileRemove(g *gocui.Gui, v *gocui.View) error {
}
func handleIgnoreFile(g *gocui.Gui, v *gocui.View) error {
- file, err := getSelectedFile(g)
- if err != nil {
- return err
- }
- if file.Tracked {
- return createErrorPanel(g, "Cannot ignore tracked files")
- }
- gitIgnore(file.Name)
- return refreshFiles(g)
+ file, err := getSelectedFile(g)
+ if err != nil {
+ return err
+ }
+ if file.Tracked {
+ return createErrorPanel(g, "Cannot ignore tracked files")
+ }
+ gitIgnore(file.Name)
+ return refreshFiles(g)
}
func renderfilesOptions(g *gocui.Gui, gitFile *GitFile) error {
- optionsMap := map[string]string{
- "tab": "next panel",
- "S": "stash files",
- "c": "commit changes",
- "o": "open",
- "s": "open in sublime",
- "i": "ignore",
- "d": "delete",
- "space": "toggle staged",
- }
- if state.HasMergeConflicts {
- optionsMap["a"] = "abort merge"
- optionsMap["m"] = "resolve merge conflicts"
- }
- if gitFile == nil {
- return renderOptionsMap(g, optionsMap)
- }
- if gitFile.Tracked {
- optionsMap["d"] = "checkout"
- }
- return renderOptionsMap(g, optionsMap)
+ optionsMap := map[string]string{
+ "tab": "next panel",
+ "S": "stash files",
+ "c": "commit changes",
+ "o": "open",
+ "s": "open in sublime",
+ "v": "open in vscode",
+ "i": "ignore",
+ "d": "delete",
+ "space": "toggle staged",
+ }
+ if state.HasMergeConflicts {
+ optionsMap["a"] = "abort merge"
+ optionsMap["m"] = "resolve merge conflicts"
+ }
+ if gitFile == nil {
+ return renderOptionsMap(g, optionsMap)
+ }
+ if gitFile.Tracked {
+ optionsMap["d"] = "checkout"
+ }
+ return renderOptionsMap(g, optionsMap)
}
func handleFileSelect(g *gocui.Gui, v *gocui.View) error {
- gitFile, err := getSelectedFile(g)
- if err != nil {
- if err != ErrNoFiles {
- return err
- }
- renderString(g, "main", "No changed files")
- colorLog(color.FgRed, "error")
- return renderfilesOptions(g, nil)
- }
- renderfilesOptions(g, &gitFile)
- var content string
- if gitFile.HasMergeConflicts {
- return refreshMergePanel(g)
- }
+ gitFile, err := getSelectedFile(g)
+ if err != nil {
+ if err != ErrNoFiles {
+ return err
+ }
+ renderString(g, "main", "No changed files")
+ return renderfilesOptions(g, nil)
+ }
+ renderfilesOptions(g, &gitFile)
+ var content string
+ if gitFile.HasMergeConflicts {
+ return refreshMergePanel(g)
+ }
- content = getDiff(gitFile)
- return renderString(g, "main", content)
+ content = getDiff(gitFile)
+ return renderString(g, "main", content)
}
func handleCommitPress(g *gocui.Gui, filesView *gocui.View) error {
- if len(stagedFiles(state.GitFiles)) == 0 && !state.HasMergeConflicts {
- return createErrorPanel(g, "There are no staged files to commit")
- }
- createPromptPanel(g, filesView, "Commit message", func(g *gocui.Gui, v *gocui.View) error {
- message := trimmedContent(v)
- if message == "" {
- return createErrorPanel(g, "You cannot commit without a commit message")
- }
- if err := gitCommit(message); err != nil {
- panic(err)
- }
- refreshFiles(g)
- return refreshCommits(g)
- })
- return nil
+ if len(stagedFiles(state.GitFiles)) == 0 && !state.HasMergeConflicts {
+ return createErrorPanel(g, "There are no staged files to commit")
+ }
+ createPromptPanel(g, filesView, "Commit message", func(g *gocui.Gui, v *gocui.View) error {
+ message := trimmedContent(v)
+ if message == "" {
+ return createErrorPanel(g, "You cannot commit without a commit message")
+ }
+ if err := gitCommit(message); err != nil {
+ panic(err)
+ }
+ refreshFiles(g)
+ return refreshCommits(g)
+ })
+ return nil
}
func genericFileOpen(g *gocui.Gui, v *gocui.View, open func(string) (string, error)) error {
- file, err := getSelectedFile(g)
- if err != nil {
- return err
- }
- _, err = open(file.Name)
- return err
+ file, err := getSelectedFile(g)
+ if err != nil {
+ return err
+ }
+ _, err = open(file.Name)
+ return err
}
func handleFileOpen(g *gocui.Gui, v *gocui.View) error {
- return genericFileOpen(g, v, openFile)
+ return genericFileOpen(g, v, openFile)
}
func handleSublimeFileOpen(g *gocui.Gui, v *gocui.View) error {
- return genericFileOpen(g, v, sublimeOpenFile)
+ return genericFileOpen(g, v, sublimeOpenFile)
+}
+func handleVsCodeFileOpen(g *gocui.Gui, v *gocui.View) error {
+ return genericFileOpen(g, v, vsCodeOpenFile)
}
func handleRefreshFiles(g *gocui.Gui, v *gocui.View) error {
@@ -177,128 +180,129 @@ func handleRefreshFiles(g *gocui.Gui, v *gocui.View) error {
}
func refreshStateGitFiles() {
- // get files to stage
- gitFiles := getGitStatusFiles()
- state.GitFiles = mergeGitStatusFiles(state.GitFiles, gitFiles)
- updateHasMergeConflictStatus()
+ // get files to stage
+ gitFiles := getGitStatusFiles()
+ state.GitFiles = mergeGitStatusFiles(state.GitFiles, gitFiles)
+ updateHasMergeConflictStatus()
}
func updateHasMergeConflictStatus() error {
- merging, err := isInMergeState()
- if err != nil {
- return err
- }
- state.HasMergeConflicts = merging
- return nil
+ merging, err := isInMergeState()
+ if err != nil {
+ return err
+ }
+ state.HasMergeConflicts = merging
+ return nil
}
func renderGitFile(gitFile GitFile, filesView *gocui.View) {
- // potentially inefficient to be instantiating these color
- // objects with each render
- red := color.New(color.FgRed)
- green := color.New(color.FgGreen)
- if !gitFile.Tracked {
- red.Fprintln(filesView, gitFile.DisplayString)
- return
- }
- 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)
- }
+ // potentially inefficient to be instantiating these color
+ // objects with each render
+ red := color.New(color.FgRed)
+ green := color.New(color.FgGreen)
+ if !gitFile.Tracked && !gitFile.HasStagedChanges {
+ red.Fprintln(filesView, gitFile.DisplayString)
+ return
+ }
+ 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)
+ }
}
func catSelectedFile(g *gocui.Gui) (string, error) {
- item, err := getSelectedFile(g)
- if err != nil {
- if err != ErrNoFiles {
- return "", err
- }
- return "", renderString(g, "main", "No file to display")
- }
- cat, err := catFile(item.Name)
- if err != nil {
- panic(err)
- }
- return cat, nil
+ item, err := getSelectedFile(g)
+ if err != nil {
+ if err != ErrNoFiles {
+ return "", err
+ }
+ return "", renderString(g, "main", "No file to display")
+ }
+ cat, err := catFile(item.Name)
+ if err != nil {
+ panic(err)
+ }
+ return cat, nil
}
func refreshFiles(g *gocui.Gui) error {
- filesView, err := g.View("files")
- if err != nil {
- return err
- }
- refreshStateGitFiles()
- filesView.Clear()
- for _, gitFile := range state.GitFiles {
- renderGitFile(gitFile, filesView)
- }
- correctCursor(filesView)
- if filesView == g.CurrentView() {
- handleFileSelect(g, filesView)
- }
- return nil
+ filesView, err := g.View("files")
+ if err != nil {
+ return err
+ }
+ refreshStateGitFiles()
+ filesView.Clear()
+ for _, gitFile := range state.GitFiles {
+ renderGitFile(gitFile, filesView)
+ }
+ correctCursor(filesView)
+ if filesView == g.CurrentView() {
+ handleFileSelect(g, filesView)
+ }
+ return nil
}
func pullFiles(g *gocui.Gui, v *gocui.View) error {
- devLog("pulling...")
- createMessagePanel(g, v, "", "Pulling...")
- go func() {
- if output, err := gitPull(); err != nil {
- createErrorPanel(g, output)
- } else {
- closeConfirmationPrompt(g)
- refreshCommits(g)
- refreshFiles(g)
- refreshStatus(g)
- devLog("pulled.")
- }
- }()
- return nil
+ devLog("pulling...")
+ createMessagePanel(g, v, "", "Pulling...")
+ go func() {
+ if output, err := gitPull(); err != nil {
+ createErrorPanel(g, output)
+ } else {
+ closeConfirmationPrompt(g)
+ refreshCommits(g)
+ refreshStatus(g)
+ devLog("pulled.")
+ }
+ refreshFiles(g)
+ }()
+ return nil
}
func pushFiles(g *gocui.Gui, v *gocui.View) error {
- devLog("pushing...")
- createMessagePanel(g, v, "", "Pushing...")
- go func() {
- if output, err := gitPush(); err != nil {
- createErrorPanel(g, output)
- } else {
- closeConfirmationPrompt(g)
- refreshCommits(g)
- refreshStatus(g)
- devLog("pushed.")
- }
- }()
- return nil
+ devLog("pushing...")
+ createMessagePanel(g, v, "", "Pushing...")
+ go func() {
+ if output, err := gitPush(); err != nil {
+ createErrorPanel(g, output)
+ } else {
+ closeConfirmationPrompt(g)
+ refreshCommits(g)
+ refreshStatus(g)
+ devLog("pushed.")
+ }
+ }()
+ return nil
}
func handleSwitchToMerge(g *gocui.Gui, v *gocui.View) error {
- mergeView, err := g.View("main")
- if err != nil {
- return err
- }
- file, err := getSelectedFile(g)
- if err != nil {
- if err != ErrNoFiles {
- return err
- }
- return nil
- }
- if !file.HasMergeConflicts {
- return nil
- }
- switchFocus(g, v, mergeView)
- return refreshMergePanel(g)
+ mergeView, err := g.View("main")
+ if err != nil {
+ return err
+ }
+ file, err := getSelectedFile(g)
+ if err != nil {
+ if err != ErrNoFiles {
+ return err
+ }
+ return nil
+ }
+ if !file.HasMergeConflicts {
+ return nil
+ }
+ switchFocus(g, v, mergeView)
+ return refreshMergePanel(g)
}
func handleAbortMerge(g *gocui.Gui, v *gocui.View) error {
- output, err := gitAbortMerge()
- if err != nil {
- return createErrorPanel(g, output)
- }
- createMessagePanel(g, v, "", "Merge aborted")
- return refreshFiles(g)
+ output, err := gitAbortMerge()
+ if err != nil {
+ return createErrorPanel(g, output)
+ }
+ createMessagePanel(g, v, "", "Merge aborted")
+ refreshStatus(g)
+ return refreshFiles(g)
}