diff --git a/files_panel.go b/files_panel.go index dd0a3f2be..2794b0178 100644 --- a/files_panel.go +++ b/files_panel.go @@ -172,7 +172,7 @@ func handleCommitPress(g *gocui.Gui, filesView *gocui.View) error { return nil } -func genericFileOpen(g *gocui.Gui, v *gocui.View, open func(string) (string, error)) error { +func genericFileOpen(g *gocui.Gui, v *gocui.View, open func(*gocui.Gui, string) (string, error)) error { file, err := getSelectedFile(g) if err != nil { if err != ErrNoFiles { @@ -180,16 +180,22 @@ func genericFileOpen(g *gocui.Gui, v *gocui.View, open func(string) (string, err } return nil } - _, err = open(file.Name) + _, err = open(g, file.Name) return err } +func handleFileEdit(g *gocui.Gui, v *gocui.View) error { + return genericFileOpen(g, v, editFile) +} + func handleFileOpen(g *gocui.Gui, v *gocui.View) error { return genericFileOpen(g, v, openFile) } + func handleSublimeFileOpen(g *gocui.Gui, v *gocui.View) error { return genericFileOpen(g, v, sublimeOpenFile) } + func handleVsCodeFileOpen(g *gocui.Gui, v *gocui.View) error { return genericFileOpen(g, v, vsCodeOpenFile) } diff --git a/gitcommands.go b/gitcommands.go index 976369317..27b567766 100644 --- a/gitcommands.go +++ b/gitcommands.go @@ -11,11 +11,12 @@ import ( "time" "github.com/fatih/color" + "github.com/jesseduffield/gocui" ) var ( - // ErrNoCheckedOutBranch : When we have no checked out branch - ErrNoCheckedOutBranch = errors.New("No currently checked out branch") + // ErrNoCheckedOutBranch : When we have no checked out branch + ErrNoCheckedOutBranch = errors.New("No currently checked out branch") ) // GitFile : A staged/unstaged file @@ -308,18 +309,57 @@ func runCommand(command string) (string, error) { return string(cmdOut), err } -func openFile(filename string) (string, error) { - return runCommand("open " + filename) -} - -func vsCodeOpenFile(filename string) (string, error) { +func vsCodeOpenFile(g *gocui.Gui, filename string) (string, error) { return runCommand("code -r " + filename) } -func sublimeOpenFile(filename string) (string, error) { +func sublimeOpenFile(g *gocui.Gui, filename string) (string, error) { return runCommand("subl " + filename) } +func openFile(g *gocui.Gui, filename string) (string, error) { + cmdName, cmdTrail := getOpenCommand() + return runCommand(cmdName + " " + cmdTrail) +} + +func editFile(g *gocui.Gui, filename string) (string, error) { + editor := os.Getenv("VISUAL") + if editor == "" { + editor = os.Getenv("EDITOR") + } + if editor == "" { + editor = "vi" + } + runSubProcess(g, editor, filename) + return "", nil +} + +func getOpenCommand() (string, string) { + //NextStep open equivalents: xdg-open (linux), cygstart (cygwin), open (OSX) + trailMap := map[string]string{ + "xdg-open": "&>/dev/null &", + "cygstart": "", + } + for name, trail := range trailMap { + if out, _ := runCommand("which " + name); out != "" { + return name, trail + } + } + return "open", "" +} + +func runSubProcess(g *gocui.Gui, cmdName string, commandArgs ...string) { + // TODO: find a way to wait for the subprocess without having to + // close and reinitialize the gui + // g.Close() // TODO: find a way to make close properly after uncommenting + cmd := exec.Command(cmdName, commandArgs...) + cmd.Stdin = os.Stdin + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + cmd.Run() + run() // start another Gui +} + func getBranchDiff(branch string, baseBranch string) (string, error) { return runCommand("git log -p -30 --color --no-merges " + branch) diff --git a/gui.go b/gui.go index 1c55c91ba..b2bda8c72 100644 --- a/gui.go +++ b/gui.go @@ -124,6 +124,9 @@ func keybindings(g *gocui.Gui) error { if err := g.SetKeybinding("files", 's', gocui.ModNone, handleSublimeFileOpen); err != nil { return err } + if err := g.SetKeybinding("files", 'e', gocui.ModNone, handleFileEdit); err != nil { + return err + } if err := g.SetKeybinding("files", 'i', gocui.ModNone, handleIgnoreFile); err != nil { return err }