1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-07-28 16:02:01 +03:00

Implement edit presets

This commit is contained in:
Stefan Haller
2023-03-26 14:04:09 +02:00
parent 7bbcec965b
commit 659d668e16
10 changed files with 557 additions and 29 deletions

View File

@ -3,8 +3,10 @@ package git_commands
import (
"os"
"strconv"
"strings"
"github.com/go-errors/errors"
"github.com/jesseduffield/lazygit/pkg/config"
"github.com/jesseduffield/lazygit/pkg/utils"
)
@ -27,7 +29,7 @@ func (self *FileCommands) Cat(fileName string) (string, error) {
return string(buf), nil
}
func (self *FileCommands) GetEditCmdStr(filename string, lineNumber int) (string, error) {
func (self *FileCommands) GetEditCmdStrLegacy(filename string, lineNumber int) (string, error) {
editor := self.UserConfig.OS.EditCommand
if editor == "" {
@ -72,3 +74,61 @@ func (self *FileCommands) GetEditCmdStr(filename string, lineNumber int) (string
}
return utils.ResolvePlaceholderString(editCmdTemplate, templateValues), nil
}
func (self *FileCommands) GetEditCmdStr(filename string) (string, bool) {
template, editInTerminal := config.GetEditTemplate(&self.UserConfig.OS, self.guessDefaultEditor)
templateValues := map[string]string{
"filename": self.cmd.Quote(filename),
}
cmdStr := utils.ResolvePlaceholderString(template, templateValues)
return cmdStr, editInTerminal
}
func (self *FileCommands) GetEditAtLineCmdStr(filename string, lineNumber int) (string, bool) {
template, editInTerminal := config.GetEditAtLineTemplate(&self.UserConfig.OS, self.guessDefaultEditor)
templateValues := map[string]string{
"filename": self.cmd.Quote(filename),
"line": strconv.Itoa(lineNumber),
}
cmdStr := utils.ResolvePlaceholderString(template, templateValues)
return cmdStr, editInTerminal
}
func (self *FileCommands) GetEditAtLineAndWaitCmdStr(filename string, lineNumber int) string {
template := config.GetEditAtLineAndWaitTemplate(&self.UserConfig.OS, self.guessDefaultEditor)
templateValues := map[string]string{
"filename": self.cmd.Quote(filename),
"line": strconv.Itoa(lineNumber),
}
cmdStr := utils.ResolvePlaceholderString(template, templateValues)
return cmdStr
}
func (self *FileCommands) guessDefaultEditor() string {
// Try to query a few places where editors get configured
editor := self.config.GetCoreEditor()
if editor == "" {
editor = self.os.Getenv("GIT_EDITOR")
}
if editor == "" {
editor = self.os.Getenv("VISUAL")
}
if editor == "" {
editor = self.os.Getenv("EDITOR")
}
if editor != "" {
// At this point, it might be more than just the name of the editor;
// e.g. it might be "code -w" or "vim -u myvim.rc". So assume that
// everything up to the first space is the editor name.
editor = strings.Split(editor, " ")[0]
}
return editor
}

View File

@ -10,7 +10,7 @@ import (
"github.com/stretchr/testify/assert"
)
func TestEditFileCmdStr(t *testing.T) {
func TestEditFileCmdStrLegacy(t *testing.T) {
type scenario struct {
filename string
configEditCommand string
@ -172,7 +172,206 @@ func TestEditFileCmdStr(t *testing.T) {
getenv: s.getenv,
})
s.test(instance.GetEditCmdStr(s.filename, 1))
s.test(instance.GetEditCmdStrLegacy(s.filename, 1))
s.runner.CheckForMissingCalls()
}
}
func TestEditFileCmd(t *testing.T) {
type scenario struct {
filename string
osConfig config.OSConfig
expectedCmdStr string
expectedEditInTerminal bool
}
scenarios := []scenario{
{
filename: "test",
osConfig: config.OSConfig{},
expectedCmdStr: `vim -- "test"`,
expectedEditInTerminal: true,
},
{
filename: "test",
osConfig: config.OSConfig{
Edit: "nano {{filename}}",
},
expectedCmdStr: `nano "test"`,
expectedEditInTerminal: true,
},
{
filename: "file/with space",
osConfig: config.OSConfig{
EditPreset: "sublime",
},
expectedCmdStr: `subl -- "file/with space"`,
expectedEditInTerminal: false,
},
}
for _, s := range scenarios {
userConfig := config.GetDefaultConfig()
userConfig.OS = s.osConfig
instance := buildFileCommands(commonDeps{
userConfig: userConfig,
})
cmdStr, editInTerminal := instance.GetEditCmdStr(s.filename)
assert.Equal(t, s.expectedCmdStr, cmdStr)
assert.Equal(t, s.expectedEditInTerminal, editInTerminal)
}
}
func TestEditFileAtLineCmd(t *testing.T) {
type scenario struct {
filename string
lineNumber int
osConfig config.OSConfig
expectedCmdStr string
expectedEditInTerminal bool
}
scenarios := []scenario{
{
filename: "test",
lineNumber: 42,
osConfig: config.OSConfig{},
expectedCmdStr: `vim +42 -- "test"`,
expectedEditInTerminal: true,
},
{
filename: "test",
lineNumber: 35,
osConfig: config.OSConfig{
EditAtLine: "nano +{{line}} {{filename}}",
},
expectedCmdStr: `nano +35 "test"`,
expectedEditInTerminal: true,
},
{
filename: "file/with space",
lineNumber: 12,
osConfig: config.OSConfig{
EditPreset: "sublime",
},
expectedCmdStr: `subl -- "file/with space":12`,
expectedEditInTerminal: false,
},
}
for _, s := range scenarios {
userConfig := config.GetDefaultConfig()
userConfig.OS = s.osConfig
instance := buildFileCommands(commonDeps{
userConfig: userConfig,
})
cmdStr, editInTerminal := instance.GetEditAtLineCmdStr(s.filename, s.lineNumber)
assert.Equal(t, s.expectedCmdStr, cmdStr)
assert.Equal(t, s.expectedEditInTerminal, editInTerminal)
}
}
func TestEditFileAtLineAndWaitCmd(t *testing.T) {
type scenario struct {
filename string
lineNumber int
osConfig config.OSConfig
expectedCmdStr string
}
scenarios := []scenario{
{
filename: "test",
lineNumber: 42,
osConfig: config.OSConfig{},
expectedCmdStr: `vim +42 -- "test"`,
},
{
filename: "file/with space",
lineNumber: 12,
osConfig: config.OSConfig{
EditPreset: "sublime",
},
expectedCmdStr: `subl --wait -- "file/with space":12`,
},
}
for _, s := range scenarios {
userConfig := config.GetDefaultConfig()
userConfig.OS = s.osConfig
instance := buildFileCommands(commonDeps{
userConfig: userConfig,
})
cmdStr := instance.GetEditAtLineAndWaitCmdStr(s.filename, s.lineNumber)
assert.Equal(t, s.expectedCmdStr, cmdStr)
}
}
func TestGuessDefaultEditor(t *testing.T) {
type scenario struct {
gitConfigMockResponses map[string]string
getenv func(string) string
expectedResult string
}
scenarios := []scenario{
{
gitConfigMockResponses: nil,
getenv: func(env string) string {
return ""
},
expectedResult: "",
},
{
gitConfigMockResponses: map[string]string{"core.editor": "nano"},
getenv: func(env string) string {
return ""
},
expectedResult: "nano",
},
{
gitConfigMockResponses: map[string]string{"core.editor": "code -w"},
getenv: func(env string) string {
return ""
},
expectedResult: "code",
},
{
gitConfigMockResponses: nil,
getenv: func(env string) string {
if env == "VISUAL" {
return "emacs"
}
return ""
},
expectedResult: "emacs",
},
{
gitConfigMockResponses: nil,
getenv: func(env string) string {
if env == "EDITOR" {
return "bbedit -w"
}
return ""
},
expectedResult: "bbedit",
},
}
for _, s := range scenarios {
instance := buildFileCommands(commonDeps{
gitConfig: git_config.NewFakeGitConfig(s.gitConfigMockResponses),
getenv: s.getenv,
})
assert.Equal(t, s.expectedResult, instance.guessDefaultEditor())
}
}