1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-04-25 12:24:47 +02:00

Expose {{.SelectedCommitRange}} to custom commands

It has fields .To and .From (the hashes of the last and the first selected
commits, respectively), and it is useful for creating git commands that act on a
range of commits.
This commit is contained in:
Stefan Haller 2024-08-28 21:31:06 +02:00
parent d768327814
commit 4baf008ac7
4 changed files with 72 additions and 0 deletions

View File

@ -297,6 +297,7 @@ Your commands can contain placeholder strings using Go's [template syntax](https
``` ```
SelectedCommit SelectedCommit
SelectedCommitRange
SelectedFile SelectedFile
SelectedPath SelectedPath
SelectedLocalBranch SelectedLocalBranch
@ -314,6 +315,11 @@ CheckedOutBranch
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). 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).
We don't support accessing all elements of a range selection yet. We might add this in the future, but as a special case you can access the range of selected commits by using `SelectedCommitRange`, which has two properties `.To` and `.From` which are the hashes of the bottom and top selected commits, respectively. This is useful for passing them to a git command that operates on a range of commits. For example, to create patches for all selected commits, you might use
```yml
command: "git format-patch {{.SelectedCommitRange.From}}^..{{.SelectedCommitRange.To}}"
```
## Keybinding collisions ## Keybinding collisions
If your custom keybinding collides with an inbuilt keybinding that is defined for the same context, only the custom keybinding will be executed. This also applies to the global context. However, one caveat is that if you have a custom keybinding defined on the global context for some key, and there is an in-built keybinding defined for the same key and for a specific context (say the 'files' context), then the in-built keybinding will take precedence. See how to change in-built keybindings [here](https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#keybindings) If your custom keybinding collides with an inbuilt keybinding that is defined for the same context, only the custom keybinding will be executed. This also applies to the global context. However, one caveat is that if you have a custom keybinding defined on the global context for some key, and there is an in-built keybinding defined for the same key and for a specific context (say the 'files' context), then the in-built keybinding will take precedence. See how to change in-built keybindings [here](https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#keybindings)

View File

@ -162,12 +162,29 @@ func worktreeShimFromModelRemote(worktree *models.Worktree) *Worktree {
} }
} }
type CommitRange struct {
From string
To string
}
func makeCommitRange(commits []*models.Commit, _ int, _ int) *CommitRange {
if len(commits) == 0 {
return nil
}
return &CommitRange{
From: commits[len(commits)-1].Hash,
To: commits[0].Hash,
}
}
// SessionState captures the current state of the application for use in custom commands // SessionState captures the current state of the application for use in custom commands
type SessionState struct { type SessionState struct {
SelectedLocalCommit *Commit // deprecated, use SelectedCommit SelectedLocalCommit *Commit // deprecated, use SelectedCommit
SelectedReflogCommit *Commit // deprecated, use SelectedCommit SelectedReflogCommit *Commit // deprecated, use SelectedCommit
SelectedSubCommit *Commit // deprecated, use SelectedCommit SelectedSubCommit *Commit // deprecated, use SelectedCommit
SelectedCommit *Commit SelectedCommit *Commit
SelectedCommitRange *CommitRange
SelectedFile *File SelectedFile *File
SelectedPath string SelectedPath string
SelectedLocalBranch *Branch SelectedLocalBranch *Branch
@ -183,14 +200,20 @@ type SessionState struct {
func (self *SessionStateLoader) call() *SessionState { func (self *SessionStateLoader) call() *SessionState {
selectedLocalCommit := commitShimFromModelCommit(self.c.Contexts().LocalCommits.GetSelected()) selectedLocalCommit := commitShimFromModelCommit(self.c.Contexts().LocalCommits.GetSelected())
selectedLocalCommitRange := makeCommitRange(self.c.Contexts().LocalCommits.GetSelectedItems())
selectedReflogCommit := commitShimFromModelCommit(self.c.Contexts().ReflogCommits.GetSelected()) selectedReflogCommit := commitShimFromModelCommit(self.c.Contexts().ReflogCommits.GetSelected())
selectedReflogCommitRange := makeCommitRange(self.c.Contexts().ReflogCommits.GetSelectedItems())
selectedSubCommit := commitShimFromModelCommit(self.c.Contexts().SubCommits.GetSelected()) selectedSubCommit := commitShimFromModelCommit(self.c.Contexts().SubCommits.GetSelected())
selectedSubCommitRange := makeCommitRange(self.c.Contexts().SubCommits.GetSelectedItems())
selectedCommit := selectedLocalCommit selectedCommit := selectedLocalCommit
selectedCommitRange := selectedLocalCommitRange
if self.c.Context().IsCurrentOrParent(self.c.Contexts().ReflogCommits) { if self.c.Context().IsCurrentOrParent(self.c.Contexts().ReflogCommits) {
selectedCommit = selectedReflogCommit selectedCommit = selectedReflogCommit
selectedCommitRange = selectedReflogCommitRange
} else if self.c.Context().IsCurrentOrParent(self.c.Contexts().SubCommits) { } else if self.c.Context().IsCurrentOrParent(self.c.Contexts().SubCommits) {
selectedCommit = selectedSubCommit selectedCommit = selectedSubCommit
selectedCommitRange = selectedSubCommitRange
} }
selectedPath := self.c.Contexts().Files.GetSelectedPath() selectedPath := self.c.Contexts().Files.GetSelectedPath()
@ -207,6 +230,7 @@ func (self *SessionStateLoader) call() *SessionState {
SelectedReflogCommit: selectedReflogCommit, SelectedReflogCommit: selectedReflogCommit,
SelectedSubCommit: selectedSubCommit, SelectedSubCommit: selectedSubCommit,
SelectedCommit: selectedCommit, SelectedCommit: selectedCommit,
SelectedCommitRange: selectedCommitRange,
SelectedLocalBranch: branchShimFromModelBranch(self.c.Contexts().Branches.GetSelected()), SelectedLocalBranch: branchShimFromModelBranch(self.c.Contexts().Branches.GetSelected()),
SelectedRemoteBranch: remoteBranchShimFromModelRemoteBranch(self.c.Contexts().RemoteBranches.GetSelected()), SelectedRemoteBranch: remoteBranchShimFromModelRemoteBranch(self.c.Contexts().RemoteBranches.GetSelected()),
SelectedRemote: remoteShimFromModelRemote(self.c.Contexts().Remotes.GetSelected()), SelectedRemote: remoteShimFromModelRemote(self.c.Contexts().Remotes.GetSelected()),

View File

@ -0,0 +1,41 @@
package custom_commands
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var SelectedCommitRange = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Use the {{ .SelectedCommitRange }} template variable",
ExtraCmdArgs: []string{},
Skip: false,
SetupRepo: func(shell *Shell) {
shell.CreateNCommits(3)
},
SetupConfig: func(cfg *config.AppConfig) {
cfg.GetUserConfig().CustomCommands = []config.CustomCommand{
{
Key: "X",
Context: "global",
Command: `git log --format="%s" {{.SelectedCommitRange.From}}^..{{.SelectedCommitRange.To}} > file.txt`,
},
}
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.Views().Commits().Focus().
Lines(
Contains("commit 03").IsSelected(),
Contains("commit 02"),
Contains("commit 01"),
)
t.GlobalPress("X")
t.FileSystem().FileContent("file.txt", Equals("commit 03\n"))
t.Views().Commits().Focus().
Press(keys.Universal.RangeSelectDown)
t.GlobalPress("X")
t.FileSystem().FileContent("file.txt", Equals("commit 03\ncommit 02\n"))
},
})

View File

@ -139,6 +139,7 @@ var tests = []*components.IntegrationTest{
custom_commands.MultipleContexts, custom_commands.MultipleContexts,
custom_commands.MultiplePrompts, custom_commands.MultiplePrompts,
custom_commands.SelectedCommit, custom_commands.SelectedCommit,
custom_commands.SelectedCommitRange,
custom_commands.SelectedPath, custom_commands.SelectedPath,
custom_commands.ShowOutputInPanel, custom_commands.ShowOutputInPanel,
custom_commands.SuggestionsCommand, custom_commands.SuggestionsCommand,