Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 13 additions & 32 deletions docs/Config.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,7 @@ If you want to change the config directory:

- MacOS: `export XDG_CONFIG_HOME="$HOME/.config"`

JSON schema is available for `config.yml` so that IntelliSense in Visual Studio Code
(completion and error checking) is automatically enabled when the [YAML Red Hat][yaml]
extension is installed. However, note that automatic schema detection only works
if your config file is in one of the standard paths mentioned above. If you
override the path to the file, you can still make IntelliSense work by adding
JSON schema is available for `config.yml` so that IntelliSense in Visual Studio Code (completion and error checking) is automatically enabled when the [YAML Red Hat][yaml] extension is installed. However, note that automatic schema detection only works if your config file is in one of the standard paths mentioned above. If you override the path to the file, you can still make IntelliSense work by adding

```yaml
# yaml-language-server: $schema=https://json.schemastore.org/lazygit.json
Expand Down Expand Up @@ -310,27 +306,20 @@ os:

### Configuring File Editing

There are two commands for opening files, `o` for "open" and `e` for "edit". `o`
acts as if the file was double-clicked in the Finder/Explorer, so it also works
for non-text files, whereas `e` opens the file in an editor. `e` can also jump
to the right line in the file if you invoke it from the staging panel, for
example.
There are two commands for opening files, `o` for "open" and `e` for "edit". `o` acts as if the file was double-clicked in the Finder/Explorer, so it also works for non-text files, whereas `e` opens the file in an editor. `e` can also jump to the right line in the file if you invoke it from the staging panel, for example.

To tell lazygit which editor to use for the `e` command, the easiest way to do
that is to provide an editPreset config, e.g.
To tell lazygit which editor to use for the `e` command, the easiest way to do that is to provide an editPreset config, e.g.

```yaml
os:
editPreset: 'vscode'
```

Supported presets are `vim`, `nvim`, `emacs`, `nano`, `vscode`, `sublime`, `bbedit`,
`kakoune`, `helix`, and `xcode`. In many cases lazygit will be able to guess the right preset
from your $(git config core.editor), or an environment variable such as $VISUAL or $EDITOR.
Supported presets are `vim`, `nvim`, `nvim-remote`, `emacs`, `nano`, `vscode`, `sublime`, `bbedit`, `kakoune`, `helix`, and `xcode`. In many cases lazygit will be able to guess the right preset from your $(git config core.editor), or an environment variable such as $VISUAL or $EDITOR.

If for some reason you are not happy with the default commands from a preset, or
there simply is no preset for your editor, you can customize the commands by
setting the `edit`, `editAtLine`, and `editAtLineAndWait` options, e.g.:
`nvim-remote` is an experimental preset for when you have invoked lazygit from within a neovim process, allowing lazygit to open the file from within the parent process rather than spawning a new one.

If for some reason you are not happy with the default commands from a preset, or there simply is no preset for your editor, you can customize the commands by setting the `edit`, `editAtLine`, and `editAtLineAndWait` options, e.g.:

```yaml
os:
Expand All @@ -341,11 +330,9 @@ os:
openDirInEditor: 'myeditor {{dir}}'
```

The `editInTerminal` option is used to decide whether lazygit needs to suspend
itself to the background before calling the editor.
The `editInTerminal` option is used to decide whether lazygit needs to suspend itself to the background before calling the editor. It should really be named `suspend` because for some cases like when lazygit is opened from within a neovim session and you're using the `nvim-remote` preset, you're technically still in a terminal. Nonetheless we're sticking with the name `editInTerminal` for backwards compatibility.

Contributions of new editor presets are welcome; see the `getPreset` function in
[`editor_presets.go`](https://github.com/jesseduffield/lazygit/blob/master/pkg/config/editor_presets.go).
Contributions of new editor presets are welcome; see the `getPreset` function in [`editor_presets.go`](https://github.com/jesseduffield/lazygit/blob/master/pkg/config/editor_presets.go).

### Overriding default config file location

Expand Down Expand Up @@ -457,8 +444,7 @@ gui:
nerdFontsVersion: "3"
```

Supported versions are "2" and "3". The deprecated config `showIcons` sets the
version to "2" for backwards compatibility.
Supported versions are "2" and "3". The deprecated config `showIcons` sets the version to "2" for backwards compatibility.

## Keybindings

Expand Down Expand Up @@ -506,9 +492,7 @@ keybinding:

## Custom pull request URLs

Some git provider setups (e.g. on-premises GitLab) can have distinct URLs for git-related calls and
the web interface/API itself. To work with those, Lazygit needs to know where it needs to create
the pull request. You can do so on your `config.yml` file using the following syntax:
Some git provider setups (e.g. on-premises GitLab) can have distinct URLs for git-related calls and the web interface/API itself. To work with those, Lazygit needs to know where it needs to create the pull request. You can do so on your `config.yml` file using the following syntax:

```yaml
services:
Expand All @@ -523,8 +507,7 @@ Where:

## Predefined commit message prefix

In situations where certain naming pattern is used for branches and commits, pattern can be used to populate
commit message with prefix that is parsed from the branch name.
In situations where certain naming pattern is used for branches and commits, pattern can be used to populate commit message with prefix that is parsed from the branch name.

Example:

Expand Down Expand Up @@ -554,9 +537,7 @@ Result:

## Launching not in a repository behaviour

By default, when launching lazygit from a directory that is not a repository,
you will be prompted to choose if you would like to initialize a repo. You can
override this behaviour in the config with one of the following:
By default, when launching lazygit from a directory that is not a repository, you will be prompted to choose if you would like to initialize a repo. You can override this behaviour in the config with one of the following:

```yaml
# for default prompting behaviour
Expand Down
14 changes: 7 additions & 7 deletions pkg/commands/git_commands/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,14 @@ func (self *FileCommands) GetEditCmdStr(filename string) (string, bool) {
}
}

template, editInTerminal := config.GetEditTemplate(&self.UserConfig.OS, self.guessDefaultEditor)
template, suspend := config.GetEditTemplate(&self.UserConfig.OS, self.guessDefaultEditor)

templateValues := map[string]string{
"filename": self.cmd.Quote(filename),
}

cmdStr := utils.ResolvePlaceholderString(template, templateValues)
return cmdStr, editInTerminal
return cmdStr, suspend
}

func (self *FileCommands) GetEditAtLineCmdStr(filename string, lineNumber int) (string, bool) {
Expand All @@ -101,15 +101,15 @@ func (self *FileCommands) GetEditAtLineCmdStr(filename string, lineNumber int) (
}
}

template, editInTerminal := config.GetEditAtLineTemplate(&self.UserConfig.OS, self.guessDefaultEditor)
template, suspend := 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
return cmdStr, suspend
}

func (self *FileCommands) GetEditAtLineAndWaitCmdStr(filename string, lineNumber int) string {
Expand All @@ -131,15 +131,15 @@ func (self *FileCommands) GetEditAtLineAndWaitCmdStr(filename string, lineNumber
return cmdStr
}

func (self *FileCommands) GetOpenDirInEditorCmdStr(path string) string {
template := config.GetOpenDirInEditorTemplate(&self.UserConfig.OS, self.guessDefaultEditor)
func (self *FileCommands) GetOpenDirInEditorCmdStr(path string) (string, bool) {
template, suspend := config.GetOpenDirInEditorTemplate(&self.UserConfig.OS, self.guessDefaultEditor)

templateValues := map[string]string{
"dir": self.cmd.Quote(path),
}

cmdStr := utils.ResolvePlaceholderString(template, templateValues)
return cmdStr
return cmdStr, suspend
}

func (self *FileCommands) guessDefaultEditor() string {
Expand Down
60 changes: 30 additions & 30 deletions pkg/commands/git_commands/file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,34 +179,34 @@ func TestEditFileCmdStrLegacy(t *testing.T) {

func TestEditFileCmd(t *testing.T) {
type scenario struct {
filename string
osConfig config.OSConfig
expectedCmdStr string
expectedEditInTerminal bool
filename string
osConfig config.OSConfig
expectedCmdStr string
suspend bool
}

scenarios := []scenario{
{
filename: "test",
osConfig: config.OSConfig{},
expectedCmdStr: `vim -- "test"`,
expectedEditInTerminal: true,
filename: "test",
osConfig: config.OSConfig{},
expectedCmdStr: `vim -- "test"`,
suspend: true,
},
{
filename: "test",
osConfig: config.OSConfig{
Edit: "nano {{filename}}",
},
expectedCmdStr: `nano "test"`,
expectedEditInTerminal: true,
expectedCmdStr: `nano "test"`,
suspend: true,
},
{
filename: "file/with space",
osConfig: config.OSConfig{
EditPreset: "sublime",
},
expectedCmdStr: `subl -- "file/with space"`,
expectedEditInTerminal: false,
expectedCmdStr: `subl -- "file/with space"`,
suspend: false,
},
}

Expand All @@ -218,46 +218,46 @@ func TestEditFileCmd(t *testing.T) {
userConfig: userConfig,
})

cmdStr, editInTerminal := instance.GetEditCmdStr(s.filename)
cmdStr, suspend := instance.GetEditCmdStr(s.filename)
assert.Equal(t, s.expectedCmdStr, cmdStr)
assert.Equal(t, s.expectedEditInTerminal, editInTerminal)
assert.Equal(t, s.suspend, suspend)
}
}

func TestEditFileAtLineCmd(t *testing.T) {
type scenario struct {
filename string
lineNumber int
osConfig config.OSConfig
expectedCmdStr string
expectedEditInTerminal bool
filename string
lineNumber int
osConfig config.OSConfig
expectedCmdStr string
suspend bool
}

scenarios := []scenario{
{
filename: "test",
lineNumber: 42,
osConfig: config.OSConfig{},
expectedCmdStr: `vim +42 -- "test"`,
expectedEditInTerminal: true,
filename: "test",
lineNumber: 42,
osConfig: config.OSConfig{},
expectedCmdStr: `vim +42 -- "test"`,
suspend: true,
},
{
filename: "test",
lineNumber: 35,
osConfig: config.OSConfig{
EditAtLine: "nano +{{line}} {{filename}}",
},
expectedCmdStr: `nano +35 "test"`,
expectedEditInTerminal: true,
expectedCmdStr: `nano +35 "test"`,
suspend: true,
},
{
filename: "file/with space",
lineNumber: 12,
osConfig: config.OSConfig{
EditPreset: "sublime",
},
expectedCmdStr: `subl -- "file/with space":12`,
expectedEditInTerminal: false,
expectedCmdStr: `subl -- "file/with space":12`,
suspend: false,
},
}

Expand All @@ -269,9 +269,9 @@ func TestEditFileAtLineCmd(t *testing.T) {
userConfig: userConfig,
})

cmdStr, editInTerminal := instance.GetEditAtLineCmdStr(s.filename, s.lineNumber)
cmdStr, suspend := instance.GetEditAtLineCmdStr(s.filename, s.lineNumber)
assert.Equal(t, s.expectedCmdStr, cmdStr)
assert.Equal(t, s.expectedEditInTerminal, editInTerminal)
assert.Equal(t, s.suspend, suspend)
}
}

Expand Down
38 changes: 23 additions & 15 deletions pkg/config/editor_presets.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,29 +28,37 @@ func GetEditAtLineAndWaitTemplate(osConfig *OSConfig, guessDefaultEditor func()
return template
}

func GetOpenDirInEditorTemplate(osConfig *OSConfig, guessDefaultEditor func() string) string {
func GetOpenDirInEditorTemplate(osConfig *OSConfig, guessDefaultEditor func() string) (string, bool) {
preset := getPreset(osConfig, guessDefaultEditor)
template := osConfig.OpenDirInEditor
if template == "" {
template = preset.openDirInEditorTemplate
}
return template
return template, getEditInTerminal(osConfig, preset)
}

type editPreset struct {
editTemplate string
editAtLineTemplate string
editAtLineAndWaitTemplate string
openDirInEditorTemplate string
editInTerminal bool
suspend bool
}

// 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 {
presets := map[string]*editPreset{
"vi": standardTerminalEditorPreset("vi"),
"vim": standardTerminalEditorPreset("vim"),
"nvim": standardTerminalEditorPreset("nvim"),
"vi": standardTerminalEditorPreset("vi"),
"vim": standardTerminalEditorPreset("vim"),
"nvim": standardTerminalEditorPreset("nvim"),
"nvim-remote": {
editTemplate: `nvim --server "$NVIM" --remote-tab {{filename}}`,
editAtLineTemplate: `nvim --server "$NVIM" --remote-tab {{filename}}; [ -z "$NVIM" ] || nvim --server "$NVIM" --remote-send ":{{line}}<CR>"`,
// No remote-wait support yet. See https://github.com/neovim/neovim/pull/17856
editAtLineAndWaitTemplate: `nvim +{{line}} {{filename}}`,
openDirInEditorTemplate: `nvim --server "$NVIM" --remote-tab {{dir}}`,
suspend: false,
},
"emacs": standardTerminalEditorPreset("emacs"),
"nano": standardTerminalEditorPreset("nano"),
"kakoune": standardTerminalEditorPreset("kak"),
Expand All @@ -59,35 +67,35 @@ func getPreset(osConfig *OSConfig, guessDefaultEditor func() string) *editPreset
editAtLineTemplate: "hx -- {{filename}}:{{line}}",
editAtLineAndWaitTemplate: "hx -- {{filename}}:{{line}}",
openDirInEditorTemplate: "hx -- {{dir}}",
editInTerminal: true,
suspend: true,
},
"vscode": {
editTemplate: "code --reuse-window -- {{filename}}",
editAtLineTemplate: "code --reuse-window --goto -- {{filename}}:{{line}}",
editAtLineAndWaitTemplate: "code --reuse-window --goto --wait -- {{filename}}:{{line}}",
openDirInEditorTemplate: "code -- {{dir}}",
editInTerminal: false,
suspend: false,
},
"sublime": {
editTemplate: "subl -- {{filename}}",
editAtLineTemplate: "subl -- {{filename}}:{{line}}",
editAtLineAndWaitTemplate: "subl --wait -- {{filename}}:{{line}}",
openDirInEditorTemplate: "subl -- {{dir}}",
editInTerminal: false,
suspend: false,
},
"bbedit": {
editTemplate: "bbedit -- {{filename}}",
editAtLineTemplate: "bbedit +{{line}} -- {{filename}}",
editAtLineAndWaitTemplate: "bbedit +{{line}} --wait -- {{filename}}",
openDirInEditorTemplate: "bbedit -- {{dir}}",
editInTerminal: false,
suspend: false,
},
"xcode": {
editTemplate: "xed -- {{filename}}",
editAtLineTemplate: "xed --line {{line}} -- {{filename}}",
editAtLineAndWaitTemplate: "xed --line {{line}} --wait -- {{filename}}",
openDirInEditorTemplate: "xed -- {{dir}}",
editInTerminal: false,
suspend: false,
},
}

Expand Down Expand Up @@ -123,13 +131,13 @@ func standardTerminalEditorPreset(editor string) *editPreset {
editAtLineTemplate: editor + " +{{line}} -- {{filename}}",
editAtLineAndWaitTemplate: editor + " +{{line}} -- {{filename}}",
openDirInEditorTemplate: editor + " -- {{dir}}",
editInTerminal: true,
suspend: true,
}
}

func getEditInTerminal(osConfig *OSConfig, preset *editPreset) bool {
if osConfig.EditInTerminal != nil {
return *osConfig.EditInTerminal
if osConfig.SuspendOnEdit != nil {
return *osConfig.SuspendOnEdit
}
return preset.editInTerminal
return preset.suspend
}
Loading