rename to filtered mode

This commit is contained in:
Jesse Duffield 2020-03-29 10:11:15 +11:00
parent 624ae45ebb
commit a2790cfe8e
14 changed files with 106 additions and 93 deletions

View file

@ -89,7 +89,7 @@ Default path for the config file:
prevScreenMode: '_' prevScreenMode: '_'
undo: 'z' undo: 'z'
redo: '<c-z>' redo: '<c-z>'
scopingMenu: <c-s> filteringMenu: <c-s>
status: status:
checkForUpdate: 'u' checkForUpdate: 'u'
recentRepos: '<enter>' recentRepos: '<enter>'

View file

@ -25,8 +25,8 @@ func main() {
repoPath := "." repoPath := "."
flaggy.String(&repoPath, "p", "path", "Path of git repo") flaggy.String(&repoPath, "p", "path", "Path of git repo")
logScope := "" filterPath := ""
flaggy.String(&logScope, "s", "scope", "scope for `git log`, typically the path of a file") flaggy.String(&filterPath, "f", "filter", "Path to filter on in `git log -- <path>`. When in filter mode, the commits, reflog, and stash are filtered based on the given path, and some operations are restricted")
dump := "" dump := ""
flaggy.AddPositionalValue(&dump, "gitargs", 1, false, "Todo file") flaggy.AddPositionalValue(&dump, "gitargs", 1, false, "Todo file")
@ -64,7 +64,7 @@ func main() {
log.Fatal(err.Error()) log.Fatal(err.Error())
} }
app, err := app.NewApp(appConfig, logScope) app, err := app.NewApp(appConfig, filterPath)
if err == nil { if err == nil {
err = app.Run() err = app.Run()

View file

@ -91,7 +91,7 @@ func newLogger(config config.AppConfigurer) *logrus.Entry {
} }
// NewApp bootstrap a new application // NewApp bootstrap a new application
func NewApp(config config.AppConfigurer, logScope string) (*App, error) { func NewApp(config config.AppConfigurer, filterPath string) (*App, error) {
app := &App{ app := &App{
closers: []io.Closer{}, closers: []io.Closer{},
Config: config, Config: config,
@ -121,7 +121,7 @@ func NewApp(config config.AppConfigurer, logScope string) (*App, error) {
if err != nil { if err != nil {
return app, err return app, err
} }
app.Gui, err = gui.NewGui(app.Log, app.GitCommand, app.OSCommand, app.Tr, config, app.Updater, logScope) app.Gui, err = gui.NewGui(app.Log, app.GitCommand, app.OSCommand, app.Tr, config, app.Updater, filterPath)
if err != nil { if err != nil {
return app, err return app, err
} }

View file

@ -84,8 +84,8 @@ func (c *CommitListBuilder) extractCommitFromLine(line string) *Commit {
} }
type GetCommitsOptions struct { type GetCommitsOptions struct {
Limit bool Limit bool
LogScope string FilterPath string
} }
// GetCommits obtains the commits of the current branch // GetCommits obtains the commits of the current branch
@ -96,7 +96,7 @@ func (c *CommitListBuilder) GetCommits(options GetCommitsOptions) ([]*Commit, er
if err != nil { if err != nil {
return nil, err return nil, err
} }
if rebaseMode != "" && options.LogScope == "" { if rebaseMode != "" && options.FilterPath == "" {
// here we want to also prepend the commits that we're in the process of rebasing // here we want to also prepend the commits that we're in the process of rebasing
rebasingCommits, err = c.getRebasingCommits(rebaseMode) rebasingCommits, err = c.getRebasingCommits(rebaseMode)
if err != nil { if err != nil {
@ -305,10 +305,10 @@ func (c *CommitListBuilder) getLogCmd(options GetCommitsOptions) *exec.Cmd {
limitFlag = "-300" limitFlag = "-300"
} }
scopeFlag := "" filterFlag := ""
if options.LogScope != "" { if options.FilterPath != "" {
scopeFlag = fmt.Sprintf(" -- %s", c.OSCommand.Quote(options.LogScope)) filterFlag = fmt.Sprintf(" --follow -- %s", c.OSCommand.Quote(options.FilterPath))
} }
return c.OSCommand.ExecutableFromString(fmt.Sprintf("git log --oneline --pretty=format:\"%%H%s%%at%s%%aN%s%%d%s%%s\" %s --abbrev=%d --date=unix %s", SEPARATION_CHAR, SEPARATION_CHAR, SEPARATION_CHAR, SEPARATION_CHAR, limitFlag, 20, scopeFlag)) return c.OSCommand.ExecutableFromString(fmt.Sprintf("git log --oneline --pretty=format:\"%%H%s%%at%s%%aN%s%%d%s%%s\" %s --abbrev=%d --date=unix %s", SEPARATION_CHAR, SEPARATION_CHAR, SEPARATION_CHAR, SEPARATION_CHAR, limitFlag, 20, filterFlag))
} }

View file

@ -156,7 +156,7 @@ func findDotGitDir(stat func(string) (os.FileInfo, error), readFile func(filenam
return strings.TrimSpace(strings.TrimPrefix(fileContent, "gitdir: ")), nil return strings.TrimSpace(strings.TrimPrefix(fileContent, "gitdir: ")), nil
} }
func (c *GitCommand) getStashEntriesWithoutScope() []*StashEntry { func (c *GitCommand) getUnfilteredStashEntries() []*StashEntry {
unescaped := "git stash list --pretty='%gs'" unescaped := "git stash list --pretty='%gs'"
rawString, _ := c.OSCommand.RunCommandWithOutput(unescaped) rawString, _ := c.OSCommand.RunCommandWithOutput(unescaped)
stashEntries := []*StashEntry{} stashEntries := []*StashEntry{}
@ -167,15 +167,15 @@ func (c *GitCommand) getStashEntriesWithoutScope() []*StashEntry {
} }
// GetStashEntries stash entries // GetStashEntries stash entries
func (c *GitCommand) GetStashEntries(scope string) []*StashEntry { func (c *GitCommand) GetStashEntries(filterPath string) []*StashEntry {
if scope == "" { if filterPath == "" {
return c.getStashEntriesWithoutScope() return c.getUnfilteredStashEntries()
} }
unescaped := fmt.Sprintf("git stash list --name-only") unescaped := fmt.Sprintf("git stash list --name-only")
rawString, err := c.OSCommand.RunCommandWithOutput(unescaped) rawString, err := c.OSCommand.RunCommandWithOutput(unescaped)
if err != nil { if err != nil {
return c.getStashEntriesWithoutScope() return c.getUnfilteredStashEntries()
} }
stashEntries := []*StashEntry{} stashEntries := []*StashEntry{}
var currentStashEntry *StashEntry var currentStashEntry *StashEntry
@ -191,12 +191,12 @@ outer:
match := re.FindStringSubmatch(lines[i]) match := re.FindStringSubmatch(lines[i])
idx, err := strconv.Atoi(match[1]) idx, err := strconv.Atoi(match[1])
if err != nil { if err != nil {
return c.getStashEntriesWithoutScope() return c.getUnfilteredStashEntries()
} }
currentStashEntry = stashEntryFromLine(lines[i], idx) currentStashEntry = stashEntryFromLine(lines[i], idx)
for i+1 < len(lines) && !isAStash(lines[i+1]) { for i+1 < len(lines) && !isAStash(lines[i+1]) {
i++ i++
if lines[i] == scope { if lines[i] == filterPath {
stashEntries = append(stashEntries, currentStashEntry) stashEntries = append(stashEntries, currentStashEntry)
continue outer continue outer
} }
@ -605,12 +605,12 @@ func (c *GitCommand) Ignore(filename string) error {
return c.OSCommand.AppendLineToFile(".gitignore", filename) return c.OSCommand.AppendLineToFile(".gitignore", filename)
} }
func (c *GitCommand) ShowCmdStr(sha string, scope string) string { func (c *GitCommand) ShowCmdStr(sha string, filterPath string) string {
scopeArg := "" filterPathArg := ""
if scope != "" { if filterPath != "" {
scopeArg = fmt.Sprintf(" -- %s", c.OSCommand.Quote(scope)) filterPathArg = fmt.Sprintf(" -- %s", c.OSCommand.Quote(filterPath))
} }
return fmt.Sprintf("git show --color=%s --no-renames --stat -p %s %s", c.colorArg(), sha, scopeArg) return fmt.Sprintf("git show --color=%s --no-renames --stat -p %s %s", c.colorArg(), sha, filterPathArg)
} }
func (c *GitCommand) GetBranchGraphCmdStr(branchName string) string { func (c *GitCommand) GetBranchGraphCmdStr(branchName string) string {
@ -1163,16 +1163,16 @@ func (c *GitCommand) FetchRemote(remoteName string) error {
// GetReflogCommits only returns the new reflog commits since the given lastReflogCommit // GetReflogCommits only returns the new reflog commits since the given lastReflogCommit
// if none is passed (i.e. it's value is nil) then we get all the reflog commits // if none is passed (i.e. it's value is nil) then we get all the reflog commits
func (c *GitCommand) GetReflogCommits(lastReflogCommit *Commit, scope string) ([]*Commit, bool, error) { func (c *GitCommand) GetReflogCommits(lastReflogCommit *Commit, filterPath string) ([]*Commit, bool, error) {
commits := make([]*Commit, 0) commits := make([]*Commit, 0)
re := regexp.MustCompile(`(\w+).*HEAD@\{([^\}]+)\}: (.*)`) re := regexp.MustCompile(`(\w+).*HEAD@\{([^\}]+)\}: (.*)`)
scopeArg := "" filterPathArg := ""
if scope != "" { if filterPath != "" {
scopeArg = fmt.Sprintf(" -- %s", c.OSCommand.Quote(scope)) filterPathArg = fmt.Sprintf(" --follow -- %s", c.OSCommand.Quote(filterPath))
} }
cmd := c.OSCommand.ExecutableFromString(fmt.Sprintf("git reflog --abbrev=20 --date=unix %s", scopeArg)) cmd := c.OSCommand.ExecutableFromString(fmt.Sprintf("git reflog --abbrev=20 --date=unix %s", filterPathArg))
onlyObtainedNewReflogCommits := false onlyObtainedNewReflogCommits := false
err := RunLineOutputCmd(cmd, func(line string) (bool, error) { err := RunLineOutputCmd(cmd, func(line string) (bool, error) {
match := re.FindStringSubmatch(line) match := re.FindStringSubmatch(line)

View file

@ -320,7 +320,7 @@ keybinding:
prevScreenMode: '_' prevScreenMode: '_'
undo: 'z' undo: 'z'
redo: '<c-z>' redo: '<c-z>'
scopingMenu: <c-s> filteringMenu: <c-s>
status: status:
checkForUpdate: 'u' checkForUpdate: 'u'
recentRepos: '<enter>' recentRepos: '<enter>'

View file

@ -263,7 +263,7 @@ func (gui *Gui) deleteNamedBranch(g *gocui.Gui, v *gocui.View, selectedBranch *c
} }
func (gui *Gui) mergeBranchIntoCheckedOutBranch(branchName string) error { func (gui *Gui) mergeBranchIntoCheckedOutBranch(branchName string) error {
if ok, err := gui.validateNotInScopedMode(); err != nil || !ok { if ok, err := gui.validateNotInFilterMode(); err != nil || !ok {
return err return err
} }
@ -290,7 +290,7 @@ func (gui *Gui) mergeBranchIntoCheckedOutBranch(branchName string) error {
} }
func (gui *Gui) handleMerge(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleMerge(g *gocui.Gui, v *gocui.View) error {
if ok, err := gui.validateNotInScopedMode(); err != nil || !ok { if ok, err := gui.validateNotInFilterMode(); err != nil || !ok {
return err return err
} }
@ -304,7 +304,7 @@ func (gui *Gui) handleRebaseOntoLocalBranch(g *gocui.Gui, v *gocui.View) error {
} }
func (gui *Gui) handleRebaseOntoBranch(selectedBranchName string) error { func (gui *Gui) handleRebaseOntoBranch(selectedBranchName string) error {
if ok, err := gui.validateNotInScopedMode(); err != nil || !ok { if ok, err := gui.validateNotInFilterMode(); err != nil || !ok {
return err return err
} }

View file

@ -62,7 +62,7 @@ func (gui *Gui) handleCommitSelect(g *gocui.Gui, v *gocui.View) error {
} }
cmd := gui.OSCommand.ExecutableFromString( cmd := gui.OSCommand.ExecutableFromString(
gui.GitCommand.ShowCmdStr(commit.Sha, gui.State.LogScope), gui.GitCommand.ShowCmdStr(commit.Sha, gui.State.FilterPath),
) )
if err := gui.newPtyTask("main", cmd); err != nil { if err := gui.newPtyTask("main", cmd); err != nil {
gui.Log.Error(err) gui.Log.Error(err)
@ -122,7 +122,7 @@ func (gui *Gui) refreshCommitsWithLimit() error {
return err return err
} }
commits, err := builder.GetCommits(commands.GetCommitsOptions{Limit: gui.State.Panels.Commits.LimitCommits, LogScope: gui.State.LogScope}) commits, err := builder.GetCommits(commands.GetCommitsOptions{Limit: gui.State.Panels.Commits.LimitCommits, FilterPath: gui.State.FilterPath})
if err != nil { if err != nil {
return err return err
} }
@ -140,7 +140,7 @@ func (gui *Gui) refreshCommitsWithLimit() error {
// specific functions // specific functions
func (gui *Gui) handleCommitSquashDown(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleCommitSquashDown(g *gocui.Gui, v *gocui.View) error {
if ok, err := gui.validateNotInScopedMode(); err != nil || !ok { if ok, err := gui.validateNotInFilterMode(); err != nil || !ok {
return err return err
} }
@ -165,7 +165,7 @@ func (gui *Gui) handleCommitSquashDown(g *gocui.Gui, v *gocui.View) error {
} }
func (gui *Gui) handleCommitFixup(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleCommitFixup(g *gocui.Gui, v *gocui.View) error {
if ok, err := gui.validateNotInScopedMode(); err != nil || !ok { if ok, err := gui.validateNotInFilterMode(); err != nil || !ok {
return err return err
} }
@ -190,7 +190,7 @@ func (gui *Gui) handleCommitFixup(g *gocui.Gui, v *gocui.View) error {
} }
func (gui *Gui) handleRenameCommit(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleRenameCommit(g *gocui.Gui, v *gocui.View) error {
if ok, err := gui.validateNotInScopedMode(); err != nil || !ok { if ok, err := gui.validateNotInFilterMode(); err != nil || !ok {
return err return err
} }
@ -215,7 +215,7 @@ func (gui *Gui) handleRenameCommit(g *gocui.Gui, v *gocui.View) error {
} }
func (gui *Gui) handleRenameCommitEditor(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleRenameCommitEditor(g *gocui.Gui, v *gocui.View) error {
if ok, err := gui.validateNotInScopedMode(); err != nil || !ok { if ok, err := gui.validateNotInFilterMode(); err != nil || !ok {
return err return err
} }
@ -265,7 +265,7 @@ func (gui *Gui) handleMidRebaseCommand(action string) (bool, error) {
} }
func (gui *Gui) handleCommitDelete(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleCommitDelete(g *gocui.Gui, v *gocui.View) error {
if ok, err := gui.validateNotInScopedMode(); err != nil || !ok { if ok, err := gui.validateNotInFilterMode(); err != nil || !ok {
return err return err
} }
@ -286,7 +286,7 @@ func (gui *Gui) handleCommitDelete(g *gocui.Gui, v *gocui.View) error {
} }
func (gui *Gui) handleCommitMoveDown(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleCommitMoveDown(g *gocui.Gui, v *gocui.View) error {
if ok, err := gui.validateNotInScopedMode(); err != nil || !ok { if ok, err := gui.validateNotInFilterMode(); err != nil || !ok {
return err return err
} }
@ -313,7 +313,7 @@ func (gui *Gui) handleCommitMoveDown(g *gocui.Gui, v *gocui.View) error {
} }
func (gui *Gui) handleCommitMoveUp(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleCommitMoveUp(g *gocui.Gui, v *gocui.View) error {
if ok, err := gui.validateNotInScopedMode(); err != nil || !ok { if ok, err := gui.validateNotInFilterMode(); err != nil || !ok {
return err return err
} }
@ -340,7 +340,7 @@ func (gui *Gui) handleCommitMoveUp(g *gocui.Gui, v *gocui.View) error {
} }
func (gui *Gui) handleCommitEdit(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleCommitEdit(g *gocui.Gui, v *gocui.View) error {
if ok, err := gui.validateNotInScopedMode(); err != nil || !ok { if ok, err := gui.validateNotInFilterMode(); err != nil || !ok {
return err return err
} }
@ -359,7 +359,7 @@ func (gui *Gui) handleCommitEdit(g *gocui.Gui, v *gocui.View) error {
} }
func (gui *Gui) handleCommitAmendTo(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleCommitAmendTo(g *gocui.Gui, v *gocui.View) error {
if ok, err := gui.validateNotInScopedMode(); err != nil || !ok { if ok, err := gui.validateNotInFilterMode(); err != nil || !ok {
return err return err
} }
@ -372,7 +372,7 @@ func (gui *Gui) handleCommitAmendTo(g *gocui.Gui, v *gocui.View) error {
} }
func (gui *Gui) handleCommitPick(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleCommitPick(g *gocui.Gui, v *gocui.View) error {
if ok, err := gui.validateNotInScopedMode(); err != nil || !ok { if ok, err := gui.validateNotInFilterMode(); err != nil || !ok {
return err return err
} }
@ -390,7 +390,7 @@ func (gui *Gui) handleCommitPick(g *gocui.Gui, v *gocui.View) error {
} }
func (gui *Gui) handleCommitRevert(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleCommitRevert(g *gocui.Gui, v *gocui.View) error {
if ok, err := gui.validateNotInScopedMode(); err != nil || !ok { if ok, err := gui.validateNotInFilterMode(); err != nil || !ok {
return err return err
} }
@ -402,7 +402,7 @@ func (gui *Gui) handleCommitRevert(g *gocui.Gui, v *gocui.View) error {
} }
func (gui *Gui) handleCopyCommit(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleCopyCommit(g *gocui.Gui, v *gocui.View) error {
if ok, err := gui.validateNotInScopedMode(); err != nil || !ok { if ok, err := gui.validateNotInFilterMode(); err != nil || !ok {
return err return err
} }
@ -445,7 +445,7 @@ func (gui *Gui) addCommitToCherryPickedCommits(index int) {
} }
func (gui *Gui) handleCopyCommitRange(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleCopyCommitRange(g *gocui.Gui, v *gocui.View) error {
if ok, err := gui.validateNotInScopedMode(); err != nil || !ok { if ok, err := gui.validateNotInFilterMode(); err != nil || !ok {
return err return err
} }
@ -471,7 +471,7 @@ func (gui *Gui) handleCopyCommitRange(g *gocui.Gui, v *gocui.View) error {
// HandlePasteCommits begins a cherry-pick rebase with the commits the user has copied // HandlePasteCommits begins a cherry-pick rebase with the commits the user has copied
func (gui *Gui) HandlePasteCommits(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) HandlePasteCommits(g *gocui.Gui, v *gocui.View) error {
if ok, err := gui.validateNotInScopedMode(); err != nil || !ok { if ok, err := gui.validateNotInFilterMode(); err != nil || !ok {
return err return err
} }
@ -551,7 +551,7 @@ func (gui *Gui) unchooseCommit(commits []*commands.Commit, i int) []*commands.Co
} }
func (gui *Gui) handleCreateFixupCommit(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleCreateFixupCommit(g *gocui.Gui, v *gocui.View) error {
if ok, err := gui.validateNotInScopedMode(); err != nil || !ok { if ok, err := gui.validateNotInFilterMode(); err != nil || !ok {
return err return err
} }
@ -575,7 +575,7 @@ func (gui *Gui) handleCreateFixupCommit(g *gocui.Gui, v *gocui.View) error {
} }
func (gui *Gui) handleSquashAllAboveFixupCommits(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleSquashAllAboveFixupCommits(g *gocui.Gui, v *gocui.View) error {
if ok, err := gui.validateNotInScopedMode(); err != nil || !ok { if ok, err := gui.validateNotInFilterMode(); err != nil || !ok {
return err return err
} }

View file

@ -217,12 +217,12 @@ type guiState struct {
PrevMainHeight int PrevMainHeight int
OldInformation string OldInformation string
StartupStage int // one of INITIAL and COMPLETE. Allows us to not load everything at once StartupStage int // one of INITIAL and COMPLETE. Allows us to not load everything at once
LogScope string // the filename that gets passed to git log FilterPath string // the filename that gets passed to git log
} }
// for now the split view will always be on // for now the split view will always be on
// NewGui builds a new gui handler // NewGui builds a new gui handler
func NewGui(log *logrus.Entry, gitCommand *commands.GitCommand, oSCommand *commands.OSCommand, tr *i18n.Localizer, config config.AppConfigurer, updater *updates.Updater, logScope string) (*Gui, error) { func NewGui(log *logrus.Entry, gitCommand *commands.GitCommand, oSCommand *commands.OSCommand, tr *i18n.Localizer, config config.AppConfigurer, updater *updates.Updater, filterPath string) (*Gui, error) {
initialState := &guiState{ initialState := &guiState{
Files: make([]*commands.File, 0), Files: make([]*commands.File, 0),
@ -250,9 +250,9 @@ func NewGui(log *logrus.Entry, gitCommand *commands.GitCommand, oSCommand *comma
EditHistory: stack.New(), EditHistory: stack.New(),
}, },
}, },
SideView: nil, SideView: nil,
Ptmx: nil, Ptmx: nil,
LogScope: logScope, FilterPath: filterPath,
} }
gui := &Gui{ gui := &Gui{
@ -511,8 +511,8 @@ func (gui *Gui) layout(g *gocui.Gui) error {
donate := color.New(color.FgMagenta, color.Underline).Sprint(gui.Tr.SLocalize("Donate")) donate := color.New(color.FgMagenta, color.Underline).Sprint(gui.Tr.SLocalize("Donate"))
information = donate + " " + information information = donate + " " + information
} }
if gui.inScopedMode() { if gui.inFilterMode() {
information = utils.ColoredString(fmt.Sprintf("%s '%s' %s", gui.Tr.SLocalize("scopingTo"), gui.State.LogScope, utils.ColoredString(gui.Tr.SLocalize("(reset)"), color.Underline)), color.FgRed, color.Bold) information = utils.ColoredString(fmt.Sprintf("%s '%s' %s", gui.Tr.SLocalize("filteringBy"), gui.State.FilterPath, utils.ColoredString(gui.Tr.SLocalize("(reset)"), color.Underline)), color.FgRed, color.Bold)
} else if len(gui.State.CherryPickedCommits) > 0 { } else if len(gui.State.CherryPickedCommits) > 0 {
information = utils.ColoredString(fmt.Sprintf("%d commits copied", len(gui.State.CherryPickedCommits)), color.FgCyan) information = utils.ColoredString(fmt.Sprintf("%d commits copied", len(gui.State.CherryPickedCommits)), color.FgCyan)
} }
@ -804,7 +804,7 @@ func (gui *Gui) layout(g *gocui.Gui) error {
if gui.g.CurrentView() == nil { if gui.g.CurrentView() == nil {
initialView := gui.getFilesView() initialView := gui.getFilesView()
if gui.inScopedMode() { if gui.inFilterMode() {
initialView = gui.getCommitsView() initialView = gui.getCommitsView()
} }
if _, err := gui.g.SetCurrentView(initialView.Name()); err != nil { if _, err := gui.g.SetCurrentView(initialView.Name()); err != nil {
@ -993,7 +993,7 @@ func (gui *Gui) Run() error {
} }
defer g.Close() defer g.Close()
if gui.inScopedMode() { if gui.inFilterMode() {
gui.State.ScreenMode = SCREEN_HALF gui.State.ScreenMode = SCREEN_HALF
} else { } else {
gui.State.ScreenMode = SCREEN_NORMAL gui.State.ScreenMode = SCREEN_NORMAL
@ -1123,10 +1123,9 @@ func (gui *Gui) handleInfoClick(g *gocui.Gui, v *gocui.View) error {
// if we're in the normal context there will be a donate button here // if we're in the normal context there will be a donate button here
// if we have ('reset') at the end then // if we have ('reset') at the end then
if gui.inScopedMode() { if gui.inFilterMode() {
if width-cx <= len(gui.Tr.SLocalize("(reset)")) { if width-cx <= len(gui.Tr.SLocalize("(reset)")) {
gui.State.LogScope = "" return gui.exitFilterMode()
return gui.Errors.ErrRestart
} else { } else {
return nil return nil
} }
@ -1177,13 +1176,20 @@ func (gui *Gui) handleMouseDownSecondary(g *gocui.Gui, v *gocui.View) error {
return nil return nil
} }
func (gui *Gui) inScopedMode() bool { func (gui *Gui) inFilterMode() bool {
return gui.State.LogScope != "" return gui.State.FilterPath != ""
} }
func (gui *Gui) validateNotInScopedMode() (bool, error) { func (gui *Gui) validateNotInFilterMode() (bool, error) {
if gui.inScopedMode() { if gui.inFilterMode() {
return false, gui.createErrorPanel("command not available in scoped mode. Either exit scoped mode or restart lazygit") return false, gui.createConfirmationPanel(gui.g, gui.g.CurrentView(), true, gui.Tr.SLocalize("MustExitFilterModeTitle"), gui.Tr.SLocalize("MustExitFilterModePrompt"), func(*gocui.Gui, *gocui.View) error {
return gui.exitFilterMode()
}, nil)
} }
return true, nil return true, nil
} }
func (gui *Gui) exitFilterMode() error {
gui.State.FilterPath = ""
return gui.Errors.ErrRestart
}

View file

@ -984,7 +984,7 @@ func (gui *Gui) GetInitialKeybindings() []*Binding {
}, },
{ {
ViewName: "", ViewName: "",
Key: gui.getKey("universal.scopingMenu"), Key: gui.getKey("universal.filteringMenu"),
Modifier: gocui.ModNone, Modifier: gocui.ModNone,
Handler: gui.handleCreateScopingMenuPanel, Handler: gui.handleCreateScopingMenuPanel,
Description: gui.Tr.SLocalize("openScopingMenu"), Description: gui.Tr.SLocalize("openScopingMenu"),

View file

@ -10,11 +10,12 @@ import (
func (gui *Gui) getSelectedReflogCommit() *commands.Commit { func (gui *Gui) getSelectedReflogCommit() *commands.Commit {
selectedLine := gui.State.Panels.ReflogCommits.SelectedLine selectedLine := gui.State.Panels.ReflogCommits.SelectedLine
if selectedLine == -1 || len(gui.State.ReflogCommits) == 0 { reflogComits := gui.State.ReflogCommits
if selectedLine == -1 || len(reflogComits) == 0 {
return nil return nil
} }
return gui.State.ReflogCommits[selectedLine] return reflogComits[selectedLine]
} }
func (gui *Gui) handleReflogCommitSelect(g *gocui.Gui, v *gocui.View) error { func (gui *Gui) handleReflogCommitSelect(g *gocui.Gui, v *gocui.View) error {
@ -37,7 +38,7 @@ func (gui *Gui) handleReflogCommitSelect(g *gocui.Gui, v *gocui.View) error {
v.FocusPoint(0, gui.State.Panels.ReflogCommits.SelectedLine) v.FocusPoint(0, gui.State.Panels.ReflogCommits.SelectedLine)
cmd := gui.OSCommand.ExecutableFromString( cmd := gui.OSCommand.ExecutableFromString(
gui.GitCommand.ShowCmdStr(commit.Sha, gui.State.LogScope), gui.GitCommand.ShowCmdStr(commit.Sha, gui.State.FilterPath),
) )
if err := gui.newPtyTask("main", cmd); err != nil { if err := gui.newPtyTask("main", cmd); err != nil {
gui.Log.Error(err) gui.Log.Error(err)
@ -52,7 +53,7 @@ func (gui *Gui) refreshReflogCommits() error {
lastReflogCommit = gui.State.ReflogCommits[0] lastReflogCommit = gui.State.ReflogCommits[0]
} }
commits, onlyObtainedNewReflogCommits, err := gui.GitCommand.GetReflogCommits(lastReflogCommit, gui.State.LogScope) commits, onlyObtainedNewReflogCommits, err := gui.GitCommand.GetReflogCommits(lastReflogCommit, gui.State.FilterPath)
if err != nil { if err != nil {
return gui.surfaceError(err) return gui.surfaceError(err)
} }

View file

@ -26,33 +26,33 @@ func (gui *Gui) handleCreateScopingMenuPanel(g *gocui.Gui, v *gocui.View) error
if fileName != "" { if fileName != "" {
menuItems = append(menuItems, &menuItem{ menuItems = append(menuItems, &menuItem{
displayString: fmt.Sprintf("%s '%s'", gui.Tr.SLocalize("scopeTo"), fileName), displayString: fmt.Sprintf("%s '%s'", gui.Tr.SLocalize("filterBy"), fileName),
onPress: func() error { onPress: func() error {
gui.State.LogScope = fileName gui.State.FilterPath = fileName
return gui.Errors.ErrRestart return gui.Errors.ErrRestart
}, },
}) })
} }
menuItems = append(menuItems, &menuItem{ menuItems = append(menuItems, &menuItem{
displayString: gui.Tr.SLocalize("fileToScopeToOption"), displayString: gui.Tr.SLocalize("filterPathOption"),
onPress: func() error { onPress: func() error {
return gui.createPromptPanel(gui.g, v, gui.Tr.SLocalize("enterFileName"), "", func(g *gocui.Gui, promptView *gocui.View) error { return gui.createPromptPanel(gui.g, v, gui.Tr.SLocalize("enterFileName"), "", func(g *gocui.Gui, promptView *gocui.View) error {
gui.State.LogScope = strings.TrimSpace(promptView.Buffer()) gui.State.FilterPath = strings.TrimSpace(promptView.Buffer())
return gui.Errors.ErrRestart return gui.Errors.ErrRestart
}) })
}, },
}) })
if gui.inScopedMode() { if gui.inFilterMode() {
menuItems = append(menuItems, &menuItem{ menuItems = append(menuItems, &menuItem{
displayString: gui.Tr.SLocalize("exitOutOfScopedMode"), displayString: gui.Tr.SLocalize("exitFilterMode"),
onPress: func() error { onPress: func() error {
gui.State.LogScope = "" gui.State.FilterPath = ""
return gui.Errors.ErrRestart return gui.Errors.ErrRestart
}, },
}) })
} }
return gui.createMenu(gui.Tr.SLocalize("scopingMenuTitle"), menuItems, createMenuOptions{showCancel: true}) return gui.createMenu(gui.Tr.SLocalize("FilteringMenuTitle"), menuItems, createMenuOptions{showCancel: true})
} }

View file

@ -47,7 +47,7 @@ func (gui *Gui) handleStashEntrySelect(g *gocui.Gui, v *gocui.View) error {
} }
func (gui *Gui) refreshStashEntries(g *gocui.Gui) error { func (gui *Gui) refreshStashEntries(g *gocui.Gui) error {
gui.State.StashEntries = gui.GitCommand.GetStashEntries(gui.State.LogScope) gui.State.StashEntries = gui.GitCommand.GetStashEntries(gui.State.FilterPath)
gui.refreshSelectedLine(&gui.State.Panels.Stash.SelectedLine, len(gui.State.StashEntries)) gui.refreshSelectedLine(&gui.State.Panels.Stash.SelectedLine, len(gui.State.StashEntries))

View file

@ -1084,8 +1084,8 @@ func addEnglish(i18nObject *i18n.Bundle) error {
ID: "gotoBottom", ID: "gotoBottom",
Other: "scroll to bottom", Other: "scroll to bottom",
}, &i18n.Message{ }, &i18n.Message{
ID: "scopingTo", ID: "filteringBy",
Other: "scoping to", Other: "filtering by",
}, &i18n.Message{ }, &i18n.Message{
ID: "(reset)", ID: "(reset)",
Other: "(reset)", Other: "(reset)",
@ -1093,20 +1093,26 @@ func addEnglish(i18nObject *i18n.Bundle) error {
ID: "openScopingMenu", ID: "openScopingMenu",
Other: "view scoping options", Other: "view scoping options",
}, &i18n.Message{ }, &i18n.Message{
ID: "scopeTo", ID: "filterBy",
Other: "scope to", Other: "filter by",
}, &i18n.Message{ }, &i18n.Message{
ID: "exitOutOfScopedMode", ID: "exitFilterMode",
Other: "stop scoping", Other: "stop filtering by path",
}, &i18n.Message{ }, &i18n.Message{
ID: "fileToScopeToOption", ID: "filterPathOption",
Other: "enter path to scope to", Other: "enter path to filter by",
}, &i18n.Message{ }, &i18n.Message{
ID: "enterFileName", ID: "enterFileName",
Other: "enter path:", Other: "enter path:",
}, &i18n.Message{ }, &i18n.Message{
ID: "scopingMenuTitle", ID: "FilteringMenuTitle",
Other: "scoping", Other: "Filtering",
}, &i18n.Message{
ID: "MustExitFilterModeTitle",
Other: "Command not available",
}, &i18n.Message{
ID: "MustExitFilterModePrompt",
Other: "Command not available in filtered mode. Exit filtered mode?",
}, },
) )
} }