Skip to content

Commit

Permalink
Expose SelectedCommit to custom commands, deprecate Selected{Local,Re…
Browse files Browse the repository at this point in the history
…flog,Sub}Commit

SelectedCommit is context-dependent and points to SelectedLocalCommit,
SelectedReflogCommit, or SelectedSubCommit depending on which panel is active.

If none of these panels is active, it returns the selected local commit, which
is probably the most useful default (e.g. when defining custom commands for the
Files panel).
  • Loading branch information
stefanhaller committed Aug 17, 2024
1 parent 1cb29ce commit 22f0d9c
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 9 deletions.
7 changes: 4 additions & 3 deletions docs/Custom_Command_Keybindings.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
12 changes: 12 additions & 0 deletions pkg/gui/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
25 changes: 19 additions & 6 deletions pkg/gui/services/custom_commands/session_state_loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -181,19 +182,31 @@ 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
}

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()),
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()),
SelectedWorktree: worktreeShimFromModelRemote(self.c.Contexts().Worktrees.GetSelected()),
CheckedOutBranch: branchShimFromModelBranch(self.refsHelper.GetCheckedOutRef()),
}
Expand Down
1 change: 1 addition & 0 deletions pkg/gui/types/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
67 changes: 67 additions & 0 deletions pkg/integration/tests/custom_commands/selected_commit.go
Original file line number Diff line number Diff line change
@@ -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"))
},
})
1 change: 1 addition & 0 deletions pkg/integration/tests/test_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ var tests = []*components.IntegrationTest{
custom_commands.MenuFromCommandsOutput,
custom_commands.MultipleContexts,
custom_commands.MultiplePrompts,
custom_commands.SelectedCommit,
custom_commands.ShowOutputInPanel,
custom_commands.SuggestionsCommand,
custom_commands.SuggestionsPreset,
Expand Down

0 comments on commit 22f0d9c

Please sign in to comment.