1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-08-08 22:36:49 +02:00

Improve template placeholders for custom commands (#3809)

- **PR Description**

Improve the template placeholders that are available for custom
commands:
- `SelectedCommit` replaces `SelectedLocalCommit`,
`SelectedReflogCommit`, and `SelectedSubCommit`
- `SelectedPath` is set to `SelectedCommitFilePath` when the CommitFiles
context is active

It still slightly bothers me that we don't make a similar unification
for `SelectedLocalBranch` and `SelectedRemoteBranch` (and others), but
it would be a bigger change to do that, and we decided in #3663 not to.

Fixes #3663.
This commit is contained in:
Stefan Haller
2024-08-17 11:29:49 +02:00
committed by GitHub
7 changed files with 158 additions and 11 deletions

View File

@@ -296,9 +296,7 @@ Here's an example using a command but not specifying anything else: so each line
Your commands can contain placeholder strings using Go's [template syntax](https://jan.newmarch.name/golang/template/chapter-template.html). The template syntax is pretty powerful, letting you do things like conditionals if you want, but for the most part you'll simply want to be accessing the fields on the following objects:
```
SelectedLocalCommit
SelectedReflogCommit
SelectedSubCommit
SelectedCommit
SelectedFile
SelectedPath
SelectedLocalBranch
@@ -311,6 +309,9 @@ SelectedWorktree
CheckedOutBranch
```
(For legacy reasons, `SelectedLocalCommit`, `SelectedReflogCommit`, and `SelectedSubCommit` are also available, but they are deprecated.)
To see what fields are available on e.g. the `SelectedFile`, see [here](https://github.com/jesseduffield/lazygit/blob/master/pkg/gui/services/custom_commands/models.go) (all the modelling lives in the same file).
## Keybinding collisions

View File

@@ -300,6 +300,18 @@ func (self *ContextMgr) IsCurrent(c types.Context) bool {
return self.Current().GetKey() == c.GetKey()
}
func (self *ContextMgr) IsCurrentOrParent(c types.Context) bool {
current := self.Current()
for current != nil {
if current.GetKey() == c.GetKey() {
return true
}
current = current.GetParentContext()
}
return false
}
func (self *ContextMgr) AllFilterable() []types.IFilterableContext {
var result []types.IFilterableContext

View File

@@ -164,9 +164,10 @@ func worktreeShimFromModelRemote(worktree *models.Worktree) *Worktree {
// SessionState captures the current state of the application for use in custom commands
type SessionState struct {
SelectedLocalCommit *Commit
SelectedReflogCommit *Commit
SelectedSubCommit *Commit
SelectedLocalCommit *Commit // deprecated, use SelectedCommit
SelectedReflogCommit *Commit // deprecated, use SelectedCommit
SelectedSubCommit *Commit // deprecated, use SelectedCommit
SelectedCommit *Commit
SelectedFile *File
SelectedPath string
SelectedLocalBranch *Branch
@@ -181,19 +182,38 @@ type SessionState struct {
}
func (self *SessionStateLoader) call() *SessionState {
selectedLocalCommit := commitShimFromModelCommit(self.c.Contexts().LocalCommits.GetSelected())
selectedReflogCommit := commitShimFromModelCommit(self.c.Contexts().ReflogCommits.GetSelected())
selectedSubCommit := commitShimFromModelCommit(self.c.Contexts().SubCommits.GetSelected())
selectedCommit := selectedLocalCommit
if self.c.Context().IsCurrentOrParent(self.c.Contexts().ReflogCommits) {
selectedCommit = selectedReflogCommit
} else if self.c.Context().IsCurrentOrParent(self.c.Contexts().SubCommits) {
selectedCommit = selectedSubCommit
}
selectedPath := self.c.Contexts().Files.GetSelectedPath()
selectedCommitFilePath := self.c.Contexts().CommitFiles.GetSelectedPath()
if self.c.Context().IsCurrent(self.c.Contexts().CommitFiles) {
selectedPath = selectedCommitFilePath
}
return &SessionState{
SelectedFile: fileShimFromModelFile(self.c.Contexts().Files.GetSelectedFile()),
SelectedPath: self.c.Contexts().Files.GetSelectedPath(),
SelectedLocalCommit: commitShimFromModelCommit(self.c.Contexts().LocalCommits.GetSelected()),
SelectedReflogCommit: commitShimFromModelCommit(self.c.Contexts().ReflogCommits.GetSelected()),
SelectedPath: selectedPath,
SelectedLocalCommit: selectedLocalCommit,
SelectedReflogCommit: selectedReflogCommit,
SelectedSubCommit: selectedSubCommit,
SelectedCommit: selectedCommit,
SelectedLocalBranch: branchShimFromModelBranch(self.c.Contexts().Branches.GetSelected()),
SelectedRemoteBranch: remoteBranchShimFromModelRemoteBranch(self.c.Contexts().RemoteBranches.GetSelected()),
SelectedRemote: remoteShimFromModelRemote(self.c.Contexts().Remotes.GetSelected()),
SelectedTag: tagShimFromModelRemote(self.c.Contexts().Tags.GetSelected()),
SelectedStashEntry: stashEntryShimFromModelRemote(self.c.Contexts().Stash.GetSelected()),
SelectedCommitFile: commitFileShimFromModelRemote(self.c.Contexts().CommitFiles.GetSelectedFile()),
SelectedCommitFilePath: self.c.Contexts().CommitFiles.GetSelectedPath(),
SelectedSubCommit: commitShimFromModelCommit(self.c.Contexts().SubCommits.GetSelected()),
SelectedCommitFilePath: selectedCommitFilePath,
SelectedWorktree: worktreeShimFromModelRemote(self.c.Contexts().Worktrees.GetSelected()),
CheckedOutBranch: branchShimFromModelBranch(self.refsHelper.GetCheckedOutRef()),
}

View File

@@ -284,6 +284,7 @@ type IContextMgr interface {
CurrentSide() Context
CurrentPopup() []Context
IsCurrent(c Context) bool
IsCurrentOrParent(c Context) bool
ForEach(func(Context))
AllList() []IListContext
AllFilterable() []IFilterableContext

View File

@@ -0,0 +1,67 @@
package custom_commands
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var SelectedCommit = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Use the {{ .SelectedCommit }} template variable in different contexts",
ExtraCmdArgs: []string{},
Skip: false,
SetupRepo: func(shell *Shell) {
shell.CreateNCommits(3)
},
SetupConfig: func(cfg *config.AppConfig) {
cfg.UserConfig.CustomCommands = []config.CustomCommand{
{
Key: "X",
Context: "global",
Command: "printf '%s' '{{ .SelectedCommit.Name }}' > file.txt",
},
}
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
// Select different commits in each of the commit views
t.Views().Commits().Focus().
NavigateToLine(Contains("commit 01"))
t.Views().ReflogCommits().Focus().
NavigateToLine(Contains("commit 02"))
t.Views().Branches().Focus().
Lines(Contains("master").IsSelected()).
PressEnter()
t.Views().SubCommits().IsFocused().
NavigateToLine(Contains("commit 03"))
// SubCommits
t.GlobalPress("X")
t.FileSystem().FileContent("file.txt", Equals("commit 03"))
t.Views().SubCommits().PressEnter()
t.GlobalPress("X")
t.FileSystem().FileContent("file.txt", Equals("commit 03"))
// ReflogCommits
t.Views().ReflogCommits().Focus()
t.GlobalPress("X")
t.FileSystem().FileContent("file.txt", Equals("commit: commit 02"))
t.Views().ReflogCommits().PressEnter()
t.GlobalPress("X")
t.FileSystem().FileContent("file.txt", Equals("commit: commit 02"))
// LocalCommits
t.Views().Commits().Focus()
t.GlobalPress("X")
t.FileSystem().FileContent("file.txt", Equals("commit 01"))
t.Views().Commits().PressEnter()
t.GlobalPress("X")
t.FileSystem().FileContent("file.txt", Equals("commit 01"))
// None of these
t.Views().Files().Focus()
t.GlobalPress("X")
t.FileSystem().FileContent("file.txt", Equals("commit 01"))
},
})

View File

@@ -0,0 +1,44 @@
package custom_commands
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var SelectedPath = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Use the {{ .SelectedPath }} template variable in different contexts",
ExtraCmdArgs: []string{},
Skip: false,
SetupRepo: func(shell *Shell) {
shell.CreateDir("folder1")
shell.CreateFileAndAdd("folder1/file1", "")
shell.Commit("commit")
shell.CreateDir("folder2")
shell.CreateFile("folder2/file2", "")
},
SetupConfig: func(cfg *config.AppConfig) {
cfg.UserConfig.CustomCommands = []config.CustomCommand{
{
Key: "X",
Context: "global",
Command: "printf '%s' '{{ .SelectedPath }}' > file.txt",
},
}
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.Views().Files().
Focus().
NavigateToLine(Contains("file2"))
t.GlobalPress("X")
t.FileSystem().FileContent("file.txt", Equals("folder2/file2"))
t.Views().Commits().
Focus().
PressEnter()
t.Views().CommitFiles().
IsFocused().
NavigateToLine(Contains("file1"))
t.GlobalPress("X")
t.FileSystem().FileContent("file.txt", Equals("folder1/file1"))
},
})

View File

@@ -124,6 +124,8 @@ var tests = []*components.IntegrationTest{
custom_commands.MenuFromCommandsOutput,
custom_commands.MultipleContexts,
custom_commands.MultiplePrompts,
custom_commands.SelectedCommit,
custom_commands.SelectedPath,
custom_commands.ShowOutputInPanel,
custom_commands.SuggestionsCommand,
custom_commands.SuggestionsPreset,