diff --git a/pkg/commands/git_commands/file.go b/pkg/commands/git_commands/file.go index 8997c34c0..a5e1f95c5 100644 --- a/pkg/commands/git_commands/file.go +++ b/pkg/commands/git_commands/file.go @@ -86,7 +86,7 @@ func (self *FileCommands) GetEditCmdStr(filenames []string) (string, bool) { } } - template, suspend := config.GetEditTemplate(&self.UserConfig().OS, self.guessDefaultEditor) + template, suspend := config.GetEditTemplate(self.os.Platform.Shell, &self.UserConfig().OS, self.guessDefaultEditor) quotedFilenames := lo.Map(filenames, func(filename string, _ int) string { return self.cmd.Quote(filename) }) templateValues := map[string]string{ @@ -105,7 +105,7 @@ func (self *FileCommands) GetEditAtLineCmdStr(filename string, lineNumber int) ( } } - template, suspend := config.GetEditAtLineTemplate(&self.UserConfig().OS, self.guessDefaultEditor) + template, suspend := config.GetEditAtLineTemplate(self.os.Platform.Shell, &self.UserConfig().OS, self.guessDefaultEditor) templateValues := map[string]string{ "filename": self.cmd.Quote(filename), @@ -124,7 +124,7 @@ func (self *FileCommands) GetEditAtLineAndWaitCmdStr(filename string, lineNumber } } - template := config.GetEditAtLineAndWaitTemplate(&self.UserConfig().OS, self.guessDefaultEditor) + template := config.GetEditAtLineAndWaitTemplate(self.os.Platform.Shell, &self.UserConfig().OS, self.guessDefaultEditor) templateValues := map[string]string{ "filename": self.cmd.Quote(filename), @@ -136,7 +136,7 @@ func (self *FileCommands) GetEditAtLineAndWaitCmdStr(filename string, lineNumber } func (self *FileCommands) GetOpenDirInEditorCmdStr(path string) (string, bool) { - template, suspend := config.GetOpenDirInEditorTemplate(&self.UserConfig().OS, self.guessDefaultEditor) + template, suspend := config.GetOpenDirInEditorTemplate(self.os.Platform.Shell, &self.UserConfig().OS, self.guessDefaultEditor) templateValues := map[string]string{ "dir": self.cmd.Quote(path), diff --git a/pkg/config/editor_presets.go b/pkg/config/editor_presets.go index 3e3d82cb4..42d9a4c0a 100644 --- a/pkg/config/editor_presets.go +++ b/pkg/config/editor_presets.go @@ -1,9 +1,12 @@ package config -import "os" +import ( + "os" + "strings" +) -func GetEditTemplate(osConfig *OSConfig, guessDefaultEditor func() string) (string, bool) { - preset := getPreset(osConfig, guessDefaultEditor) +func GetEditTemplate(shell string, osConfig *OSConfig, guessDefaultEditor func() string) (string, bool) { + preset := getPreset(shell, osConfig, guessDefaultEditor) template := osConfig.Edit if template == "" { template = preset.editTemplate @@ -12,8 +15,8 @@ func GetEditTemplate(osConfig *OSConfig, guessDefaultEditor func() string) (stri return template, getEditInTerminal(osConfig, preset) } -func GetEditAtLineTemplate(osConfig *OSConfig, guessDefaultEditor func() string) (string, bool) { - preset := getPreset(osConfig, guessDefaultEditor) +func GetEditAtLineTemplate(shell string, osConfig *OSConfig, guessDefaultEditor func() string) (string, bool) { + preset := getPreset(shell, osConfig, guessDefaultEditor) template := osConfig.EditAtLine if template == "" { template = preset.editAtLineTemplate @@ -21,8 +24,8 @@ func GetEditAtLineTemplate(osConfig *OSConfig, guessDefaultEditor func() string) return template, getEditInTerminal(osConfig, preset) } -func GetEditAtLineAndWaitTemplate(osConfig *OSConfig, guessDefaultEditor func() string) string { - preset := getPreset(osConfig, guessDefaultEditor) +func GetEditAtLineAndWaitTemplate(shell string, osConfig *OSConfig, guessDefaultEditor func() string) string { + preset := getPreset(shell, osConfig, guessDefaultEditor) template := osConfig.EditAtLineAndWait if template == "" { template = preset.editAtLineAndWaitTemplate @@ -30,8 +33,8 @@ func GetEditAtLineAndWaitTemplate(osConfig *OSConfig, guessDefaultEditor func() return template } -func GetOpenDirInEditorTemplate(osConfig *OSConfig, guessDefaultEditor func() string) (string, bool) { - preset := getPreset(osConfig, guessDefaultEditor) +func GetOpenDirInEditorTemplate(shell string, osConfig *OSConfig, guessDefaultEditor func() string) (string, bool) { + preset := getPreset(shell, osConfig, guessDefaultEditor) template := osConfig.OpenDirInEditor if template == "" { template = preset.openDirInEditorTemplate @@ -50,17 +53,28 @@ type editPreset struct { func returnBool(a bool) func() bool { return (func() bool { return a }) } // IF YOU ADD A PRESET TO THIS FUNCTION YOU MUST UPDATE THE `Supported presets` SECTION OF docs/Config.md -func getPreset(osConfig *OSConfig, guessDefaultEditor func() string) *editPreset { +func getPreset(shell string, osConfig *OSConfig, guessDefaultEditor func() string) *editPreset { + var nvimRemoteEditTemplate, nvimRemoteEditAtLineTemplate, nvimRemoteOpenDirInEditorTemplate string + // By default fish doesn't have SHELL variable set, but it does have FISH_VERSION since Nov 2012. + if (strings.HasSuffix(shell, "fish")) || (os.Getenv("FISH_VERSION") != "") { + nvimRemoteEditTemplate = `begin; if test -z "$NVIM"; nvim -- {{filename}}; else; nvim --server "$NVIM" --remote-send "q"; nvim --server "$NVIM" --remote-tab {{filename}}; end; end` + nvimRemoteEditAtLineTemplate = `begin; if test -z "$NVIM"; nvim +{{line}} -- {{filename}}; else; nvim --server "$NVIM" --remote-send "q"; nvim --server "$NVIM" --remote-tab {{filename}}; nvim --server "$NVIM" --remote-send ":{{line}}"; end; end` + nvimRemoteOpenDirInEditorTemplate = `begin; if test -z "$NVIM"; nvim -- {{dir}}; else; nvim --server "$NVIM" --remote-send "q"; nvim --server "$NVIM" --remote-tab {{dir}}; end; end` + } else { + nvimRemoteEditTemplate = `[ -z "$NVIM" ] && (nvim -- {{filename}}) || (nvim --server "$NVIM" --remote-send "q" && nvim --server "$NVIM" --remote-tab {{filename}})` + nvimRemoteEditAtLineTemplate = `[ -z "$NVIM" ] && (nvim +{{line}} -- {{filename}}) || (nvim --server "$NVIM" --remote-send "q" && nvim --server "$NVIM" --remote-tab {{filename}} && nvim --server "$NVIM" --remote-send ":{{line}}")` + nvimRemoteOpenDirInEditorTemplate = `[ -z "$NVIM" ] && (nvim -- {{dir}}) || (nvim --server "$NVIM" --remote-send "q" && nvim --server "$NVIM" --remote-tab {{dir}})` + } presets := map[string]*editPreset{ "vi": standardTerminalEditorPreset("vi"), "vim": standardTerminalEditorPreset("vim"), "nvim": standardTerminalEditorPreset("nvim"), "nvim-remote": { - editTemplate: `[ -z "$NVIM" ] && (nvim -- {{filename}}) || (nvim --server "$NVIM" --remote-send "q" && nvim --server "$NVIM" --remote-tab {{filename}})`, - editAtLineTemplate: `[ -z "$NVIM" ] && (nvim +{{line}} -- {{filename}}) || (nvim --server "$NVIM" --remote-send "q" && nvim --server "$NVIM" --remote-tab {{filename}} && nvim --server "$NVIM" --remote-send ":{{line}}")`, + editTemplate: nvimRemoteEditTemplate, + editAtLineTemplate: nvimRemoteEditAtLineTemplate, // No remote-wait support yet. See https://github.com/neovim/neovim/pull/17856 editAtLineAndWaitTemplate: `nvim +{{line}} {{filename}}`, - openDirInEditorTemplate: `[ -z "$NVIM" ] && (nvim -- {{dir}}) || (nvim --server "$NVIM" --remote-send "q" && nvim --server "$NVIM" --remote-tab {{dir}})`, + openDirInEditorTemplate: nvimRemoteOpenDirInEditorTemplate, suspend: func() bool { _, ok := os.LookupEnv("NVIM") return !ok diff --git a/pkg/config/editor_presets_test.go b/pkg/config/editor_presets_test.go index 1a6cb0963..d7c56965a 100644 --- a/pkg/config/editor_presets_test.go +++ b/pkg/config/editor_presets_test.go @@ -111,15 +111,15 @@ func TestGetEditTemplate(t *testing.T) { } for _, s := range scenarios { t.Run(s.name, func(t *testing.T) { - template, suspend := GetEditTemplate(s.osConfig, s.guessDefaultEditor) + template, suspend := GetEditTemplate("bash", s.osConfig, s.guessDefaultEditor) assert.Equal(t, s.expectedEditTemplate, template) assert.Equal(t, s.expectedSuspend, suspend) - template, suspend = GetEditAtLineTemplate(s.osConfig, s.guessDefaultEditor) + template, suspend = GetEditAtLineTemplate("bash", s.osConfig, s.guessDefaultEditor) assert.Equal(t, s.expectedEditAtLineTemplate, template) assert.Equal(t, s.expectedSuspend, suspend) - template = GetEditAtLineAndWaitTemplate(s.osConfig, s.guessDefaultEditor) + template = GetEditAtLineAndWaitTemplate("bash", s.osConfig, s.guessDefaultEditor) assert.Equal(t, s.expectedEditAtLineAndWaitTemplate, template) }) }