diff --git a/docs/Keybindings.md b/docs/Keybindings.md index 2b9f9d952..2a1b1817f 100644 --- a/docs/Keybindings.md +++ b/docs/Keybindings.md @@ -1,16 +1,25 @@ # Keybindings: ## Global: +
   /hjkl:               navigate
-  PgUp/PgDn or ctrl+u/ctrl+d:   scroll diff panel 
+  PgUp/PgDn or ctrl+u/ctrl+d:   scroll diff panel
                                      (for PgUp and PgDn, use fn+up/fn+down on osx)
   q:                                quit
   p:                                pull
   shift+P:                         push
 
+## Status Panel: + +
+  e:        edit config file
+  o:        open config file
+
+ ## Files Panel: +
   space:    toggle staged
   c:        commit changes
@@ -27,6 +36,7 @@
 
## Branches Panel: +
   space:   checkout branch
   f:       force checkout branch
@@ -37,6 +47,7 @@
 
## Commits Panel: +
   s:       squash down (only available for topmost commit)
   r:       rename commit
@@ -44,6 +55,7 @@
 
## Stash Panel: +
   space:   apply
   g:       pop
@@ -51,6 +63,7 @@
 
## Popup Panel: +
   esc:     close/cancel
   enter:   confirm
@@ -58,6 +71,7 @@
 
## Resolving Merge Conflicts (Diff Panel): +
   /hl: navigate conflicts
   /kj: select hunk
diff --git a/pkg/commands/os.go b/pkg/commands/os.go
index f5efbac63..32514a419 100644
--- a/pkg/commands/os.go
+++ b/pkg/commands/os.go
@@ -131,7 +131,7 @@ func (c *OSCommand) OpenFile(filename string) (*exec.Cmd, error) {
 	if err != nil {
 		return nil, err
 	}
-	err = c.RunCommand(cmdName + " " + filename + cmdTrail) // TODO: test on linux
+	err = c.RunCommand(cmdName + " " + c.Quote(filename) + cmdTrail) // TODO: test on linux
 	return nil, err
 }
 
diff --git a/pkg/gui/files_panel.go b/pkg/gui/files_panel.go
index 27589bc19..166af4108 100644
--- a/pkg/gui/files_panel.go
+++ b/pkg/gui/files_panel.go
@@ -228,15 +228,9 @@ func (gui *Gui) PrepareSubProcess(g *gocui.Gui, commands ...string) error {
 	return nil
 }
 
-func (gui *Gui) genericFileOpen(g *gocui.Gui, v *gocui.View, open func(string) (*exec.Cmd, error)) error {
-	file, err := gui.getSelectedFile(g)
-	if err != nil {
-		if err != gui.Errors.ErrNoFiles {
-			return err
-		}
-		return nil
-	}
-	sub, err := open(file.Name)
+func (gui *Gui) genericFileOpen(g *gocui.Gui, v *gocui.View, filename string, open func(string) (*exec.Cmd, error)) error {
+
+	sub, err := open(filename)
 	if err != nil {
 		return gui.createErrorPanel(g, err.Error())
 	}
@@ -248,19 +242,35 @@ func (gui *Gui) genericFileOpen(g *gocui.Gui, v *gocui.View, open func(string) (
 }
 
 func (gui *Gui) handleFileEdit(g *gocui.Gui, v *gocui.View) error {
-	return gui.genericFileOpen(g, v, gui.OSCommand.EditFile)
+	file, err := gui.getSelectedFile(g)
+	if err != nil {
+		return err
+	}
+	return gui.genericFileOpen(g, v, file.Name, gui.OSCommand.EditFile)
 }
 
 func (gui *Gui) handleFileOpen(g *gocui.Gui, v *gocui.View) error {
-	return gui.genericFileOpen(g, v, gui.OSCommand.OpenFile)
+	file, err := gui.getSelectedFile(g)
+	if err != nil {
+		return err
+	}
+	return gui.genericFileOpen(g, v, file.Name, gui.OSCommand.OpenFile)
 }
 
 func (gui *Gui) handleSublimeFileOpen(g *gocui.Gui, v *gocui.View) error {
-	return gui.genericFileOpen(g, v, gui.OSCommand.SublimeOpenFile)
+	file, err := gui.getSelectedFile(g)
+	if err != nil {
+		return err
+	}
+	return gui.genericFileOpen(g, v, file.Name, gui.OSCommand.SublimeOpenFile)
 }
 
 func (gui *Gui) handleVsCodeFileOpen(g *gocui.Gui, v *gocui.View) error {
-	return gui.genericFileOpen(g, v, gui.OSCommand.VsCodeOpenFile)
+	file, err := gui.getSelectedFile(g)
+	if err != nil {
+		return err
+	}
+	return gui.genericFileOpen(g, v, file.Name, gui.OSCommand.VsCodeOpenFile)
 }
 
 func (gui *Gui) handleRefreshFiles(g *gocui.Gui, v *gocui.View) error {
diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go
index 05d0a1ae0..1e7b6156b 100644
--- a/pkg/gui/gui.go
+++ b/pkg/gui/gui.go
@@ -257,7 +257,9 @@ func (gui *Gui) layout(g *gocui.Gui) error {
 		v.BgColor = gocui.ColorDefault
 		v.FgColor = gocui.ColorGreen
 		v.Frame = false
-		gui.renderString(g, "version", version)
+		if err := gui.renderString(g, "version", version); err != nil {
+			return err
+		}
 
 		// these are only called once
 		gui.handleFileSelect(g, filesView)
@@ -265,7 +267,9 @@ func (gui *Gui) layout(g *gocui.Gui) error {
 		gui.refreshBranches(g)
 		gui.refreshCommits(g)
 		gui.refreshStashEntries(g)
-		gui.nextView(g, nil)
+		if err := gui.switchFocus(g, nil, filesView); err != nil {
+			return err
+		}
 	}
 
 	gui.resizePopupPanels(g)
diff --git a/pkg/gui/keybindings.go b/pkg/gui/keybindings.go
index b4f2bdc57..68cccda6b 100644
--- a/pkg/gui/keybindings.go
+++ b/pkg/gui/keybindings.go
@@ -23,6 +23,8 @@ func (gui *Gui) keybindings(g *gocui.Gui) error {
 		{ViewName: "", Key: 'P', Modifier: gocui.ModNone, Handler: gui.pushFiles},
 		{ViewName: "", Key: 'p', Modifier: gocui.ModNone, Handler: gui.pullFiles},
 		{ViewName: "", Key: 'R', Modifier: gocui.ModNone, Handler: gui.handleRefresh},
+		{ViewName: "status", Key: 'e', Modifier: gocui.ModNone, Handler: gui.handleEditConfig},
+		{ViewName: "status", Key: 'o', Modifier: gocui.ModNone, Handler: gui.handleOpenConfig},
 		{ViewName: "files", Key: 'c', Modifier: gocui.ModNone, Handler: gui.handleCommitPress},
 		{ViewName: "files", Key: 'C', Modifier: gocui.ModNone, Handler: gui.handleCommitEditorPress},
 		{ViewName: "files", Key: gocui.KeySpace, Modifier: gocui.ModNone, Handler: gui.handleFilePress},
@@ -70,7 +72,7 @@ func (gui *Gui) keybindings(g *gocui.Gui) error {
 
 	// Would make these keybindings global but that interferes with editing
 	// input in the confirmation panel
-	for _, viewName := range []string{"files", "branches", "commits", "stash"} {
+	for _, viewName := range []string{"status", "files", "branches", "commits", "stash"} {
 		bindings = append(bindings, []Binding{
 			{ViewName: viewName, Key: gocui.KeyTab, Modifier: gocui.ModNone, Handler: gui.nextView},
 			{ViewName: viewName, Key: gocui.KeyArrowLeft, Modifier: gocui.ModNone, Handler: gui.previousView},
diff --git a/pkg/gui/status_panel.go b/pkg/gui/status_panel.go
index 67f133738..544f5e880 100644
--- a/pkg/gui/status_panel.go
+++ b/pkg/gui/status_panel.go
@@ -40,3 +40,24 @@ func (gui *Gui) refreshStatus(g *gocui.Gui) error {
 
 	return nil
 }
+
+func (gui *Gui) renderStatusOptions(g *gocui.Gui) error {
+	return gui.renderOptionsMap(g, map[string]string{
+		"o": gui.Tr.SLocalize("OpenConfig"),
+		"e": gui.Tr.SLocalize("EditConfig"),
+	})
+}
+
+func (gui *Gui) handleStatusSelect(g *gocui.Gui, v *gocui.View) error {
+	return gui.renderStatusOptions(g)
+}
+
+func (gui *Gui) handleOpenConfig(g *gocui.Gui, v *gocui.View) error {
+	filename := gui.Config.GetUserConfig().ConfigFileUsed()
+	return gui.genericFileOpen(g, v, filename, gui.OSCommand.OpenFile)
+}
+
+func (gui *Gui) handleEditConfig(g *gocui.Gui, v *gocui.View) error {
+	filename := gui.Config.GetUserConfig().ConfigFileUsed()
+	return gui.genericFileOpen(g, v, filename, gui.OSCommand.EditFile)
+}
diff --git a/pkg/gui/view_helpers.go b/pkg/gui/view_helpers.go
index 95324ecde..46fc79e40 100644
--- a/pkg/gui/view_helpers.go
+++ b/pkg/gui/view_helpers.go
@@ -9,7 +9,7 @@ import (
 	"github.com/jesseduffield/gocui"
 )
 
-var cyclableViews = []string{"files", "branches", "commits", "stash"}
+var cyclableViews = []string{"status", "files", "branches", "commits", "stash"}
 
 func (gui *Gui) refreshSidePanels(g *gocui.Gui) error {
 	gui.refreshBranches(g)
@@ -81,6 +81,8 @@ func (gui *Gui) newLineFocused(g *gocui.Gui, v *gocui.View) error {
 	mainView.SetOrigin(0, 0)
 
 	switch v.Name() {
+	case "status":
+		return gui.handleStatusSelect(g, v)
 	case "files":
 		return gui.handleFileSelect(g, v)
 	case "branches":
diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go
index d67bd9053..c6d1d1379 100644
--- a/pkg/i18n/english.go
+++ b/pkg/i18n/english.go
@@ -294,6 +294,12 @@ func addEnglish(i18nObject *i18n.Bundle) {
 		}, &i18n.Message{
 			ID:    "MergeAborted",
 			Other: "Merge aborted",
+		}, &i18n.Message{
+			ID:    "OpenConfig",
+			Other: "open config file",
+		}, &i18n.Message{
+			ID:    "EditConfig",
+			Other: "edit config file",
 		},
 	)
 }