diff options
author | Jesse Duffield <jessedduffield@gmail.com> | 2018-09-19 19:55:14 +1000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-09-19 19:55:14 +1000 |
commit | 3072c93e131152d3898ff1e98cc7999c79ecd195 (patch) | |
tree | 922550b1d5d163969d223998a7b6de135c0a5fad | |
parent | fce895ed0d5cafdb9e054795d4f159d1dbeec2bd (diff) | |
parent | 5a76b579528bb90b5aff388f8aa68594c22a03c3 (diff) |
Merge pull request #280 from jesseduffield/hotfix/cursor-positioning
Fix cursor positioning bugs
-rw-r--r-- | pkg/commands/branch.go | 6 | ||||
-rw-r--r-- | pkg/commands/commit.go | 26 | ||||
-rw-r--r-- | pkg/commands/file.go | 36 | ||||
-rw-r--r-- | pkg/commands/git.go | 34 | ||||
-rw-r--r-- | pkg/commands/git_structs.go | 27 | ||||
-rw-r--r-- | pkg/commands/git_test.go | 66 | ||||
-rw-r--r-- | pkg/commands/stash_entry.go | 13 | ||||
-rw-r--r-- | pkg/git/branch_list_builder.go | 32 | ||||
-rw-r--r-- | pkg/gui/branches_panel.go | 12 | ||||
-rw-r--r-- | pkg/gui/commits_panel.go | 27 | ||||
-rw-r--r-- | pkg/gui/files_panel.go | 45 | ||||
-rw-r--r-- | pkg/gui/gui.go | 15 | ||||
-rw-r--r-- | pkg/gui/keybindings.go | 35 | ||||
-rw-r--r-- | pkg/gui/menu_panel.go | 106 | ||||
-rw-r--r-- | pkg/gui/options_menu_panel.go | 51 | ||||
-rw-r--r-- | pkg/gui/stash_panel.go | 11 | ||||
-rw-r--r-- | pkg/gui/view_helpers.go | 39 | ||||
-rw-r--r-- | pkg/utils/utils.go | 105 | ||||
-rw-r--r-- | pkg/utils/utils_test.go | 209 |
19 files changed, 637 insertions, 258 deletions
diff --git a/pkg/commands/branch.go b/pkg/commands/branch.go index 13c26e766..19553a26b 100644 --- a/pkg/commands/branch.go +++ b/pkg/commands/branch.go @@ -14,9 +14,9 @@ type Branch struct { Recency string } -// GetDisplayString returns the dispaly string of branch -func (b *Branch) GetDisplayString() string { - return utils.WithPadding(b.Recency, 4) + utils.ColoredString(b.Name, b.GetColor()) +// GetDisplayStrings returns the dispaly string of branch +func (b *Branch) GetDisplayStrings() []string { + return []string{b.Recency, utils.ColoredString(b.Name, b.GetColor())} } // GetColor branch color diff --git a/pkg/commands/commit.go b/pkg/commands/commit.go new file mode 100644 index 000000000..37c3e9525 --- /dev/null +++ b/pkg/commands/commit.go @@ -0,0 +1,26 @@ +package commands + +import ( + "github.com/fatih/color" +) + +// Commit : A git commit +type Commit struct { + Sha string + Name string + Pushed bool + DisplayString string +} + +func (c *Commit) GetDisplayStrings() []string { + red := color.New(color.FgRed) + yellow := color.New(color.FgYellow) + white := color.New(color.FgWhite) + + shaColor := yellow + if c.Pushed { + shaColor = red + } + + return []string{shaColor.Sprint(c.Sha), white.Sprint(c.Name)} +} diff --git a/pkg/commands/file.go b/pkg/commands/file.go new file mode 100644 index 000000000..8fcd9aff9 --- /dev/null +++ b/pkg/commands/file.go @@ -0,0 +1,36 @@ +package commands + +import "github.com/fatih/color" + +// File : A file from git status +// duplicating this for now +type File struct { + Name string + HasStagedChanges bool + HasUnstagedChanges bool + Tracked bool + Deleted bool + HasMergeConflicts bool + DisplayString string + Type string // one of 'file', 'directory', and 'other' +} + +// GetDisplayStrings returns the display string of a file +func (f *File) GetDisplayStrings() []string { + // potentially inefficient to be instantiating these color + // objects with each render + red := color.New(color.FgRed) + green := color.New(color.FgGreen) + if !f.Tracked && !f.HasStagedChanges { + return []string{red.Sprint(f.DisplayString)} + } + + output := green.Sprint(f.DisplayString[0:1]) + output += red.Sprint(f.DisplayString[1:3]) + if f.HasUnstagedChanges { + output += red.Sprint(f.Name) + } else { + output += green.Sprint(f.Name) + } + return []string{output} +} diff --git a/pkg/commands/git.go b/pkg/commands/git.go index a106d8dce..c37ca9b47 100644 --- a/pkg/commands/git.go +++ b/pkg/commands/git.go @@ -105,17 +105,17 @@ func NewGitCommand(log *logrus.Entry, osCommand *OSCommand, tr *i18n.Localizer) } // GetStashEntries stash entryies -func (c *GitCommand) GetStashEntries() []StashEntry { +func (c *GitCommand) GetStashEntries() []*StashEntry { rawString, _ := c.OSCommand.RunCommandWithOutput("git stash list --pretty='%gs'") - stashEntries := []StashEntry{} + stashEntries := []*StashEntry{} for i, line := range utils.SplitLines(rawString) { stashEntries = append(stashEntries, stashEntryFromLine(line, i)) } return stashEntries } -func stashEntryFromLine(line string, index int) StashEntry { - return StashEntry{ +func stashEntryFromLine(line string, index int) *StashEntry { + return &StashEntry{ Name: line, Index: index, DisplayString: line, @@ -128,10 +128,10 @@ func (c *GitCommand) GetStashEntryDiff(index int) (string, error) { } // GetStatusFiles git status files -func (c *GitCommand) GetStatusFiles() []File { +func (c *GitCommand) GetStatusFiles() []*File { statusOutput, _ := c.GitStatus() statusStrings := utils.SplitLines(statusOutput) - files := []File{} + files := []*File{} for _, statusString := range statusStrings { change := statusString[0:2] @@ -141,7 +141,7 @@ func (c *GitCommand) GetStatusFiles() []File { _, untracked := map[string]bool{"??": true, "A ": true, "AM": true}[change] _, hasNoStagedChanges := map[string]bool{" ": true, "U": true, "?": true}[stagedChange] - file := File{ + file := &File{ Name: filename, DisplayString: statusString, HasStagedChanges: !hasNoStagedChanges, @@ -169,7 +169,7 @@ func (c *GitCommand) StashSave(message string) error { } // MergeStatusFiles merge status files -func (c *GitCommand) MergeStatusFiles(oldFiles, newFiles []File) []File { +func (c *GitCommand) MergeStatusFiles(oldFiles, newFiles []*File) []*File { if len(oldFiles) == 0 { return newFiles } @@ -177,7 +177,7 @@ func (c *GitCommand) MergeStatusFiles(oldFiles, newFiles []File) []File { appendedIndexes := []int{} // retain position of files we already could see - result := []File{} + result := []*File{} for _, oldFile := range oldFiles { for newIndex, newFile := range newFiles { if oldFile.Name == newFile.Name { @@ -231,9 +231,9 @@ func (c *GitCommand) UpstreamDifferenceCount() (string, string) { return strings.TrimSpace(pushableCount), strings.TrimSpace(pullableCount) } -// getCommitsToPush Returns the sha's of the commits that have not yet been pushed +// GetCommitsToPush Returns the sha's of the commits that have not yet been pushed // to the remote branch of the current branch, a map is returned to ease look up -func (c *GitCommand) getCommitsToPush() map[string]bool { +func (c *GitCommand) GetCommitsToPush() map[string]bool { pushables := map[string]bool{} o, err := c.OSCommand.RunCommandWithOutput("git rev-list @{u}..head --abbrev-commit") if err != nil { @@ -413,7 +413,7 @@ func (c *GitCommand) IsInMergeState() (bool, error) { } // RemoveFile directly -func (c *GitCommand) RemoveFile(file File) error { +func (c *GitCommand) RemoveFile(file *File) error { // if the file isn't tracked, we assume you want to delete it if file.HasStagedChanges { if err := c.OSCommand.RunCommand(fmt.Sprintf("git reset -- %s", file.Name)); err != nil { @@ -460,16 +460,16 @@ func (c *GitCommand) GetBranchGraph(branchName string) (string, error) { } // GetCommits obtains the commits of the current branch -func (c *GitCommand) GetCommits() []Commit { - pushables := c.getCommitsToPush() +func (c *GitCommand) GetCommits() []*Commit { + pushables := c.GetCommitsToPush() log := c.GetLog() - commits := []Commit{} + commits := []*Commit{} // now we can split it up and turn it into commits for _, line := range utils.SplitLines(log) { splitLine := strings.Split(line, " ") sha := splitLine[0] _, pushed := pushables[sha] - commits = append(commits, Commit{ + commits = append(commits, &Commit{ Sha: sha, Name: strings.Join(splitLine[1:], " "), Pushed: pushed, @@ -508,7 +508,7 @@ func (c *GitCommand) Show(sha string) string { } // Diff returns the diff of a file -func (c *GitCommand) Diff(file File) string { +func (c *GitCommand) Diff(file *File) string { cachedArg := "" fileName := c.OSCommand.Quote(file.Name) if file.HasStagedChanges && !file.HasUnstagedChanges { diff --git a/pkg/commands/git_structs.go b/pkg/commands/git_structs.go index 2b3b3f2db..1590ce32e 100644 --- a/pkg/commands/git_structs.go +++ b/pkg/commands/git_structs.go @@ -1,32 +1,5 @@ package commands -// File : A staged/unstaged file -type File struct { - Name string - HasStagedChanges bool - HasUnstagedChanges bool - Tracked bool - Deleted bool - HasMergeConflicts bool - DisplayString string - Type string // one of 'file', 'directory', and 'other' -} - -// Commit : A git commit -type Commit struct { - Sha string - Name string - Pushed bool - DisplayString string -} - -// StashEntry : A git stash entry -type StashEntry struct { - Index int - Name string - DisplayString string -} - // Conflict : A git conflict with a start middle and end corresponding to line // numbers in the file where the conflict bars appear type Conflict struct { diff --git a/pkg/commands/git_test.go b/pkg/commands/git_test.go index aedf5253b..790a34690 100644 --- a/pkg/commands/git_test.go +++ b/pkg/commands/git_test.go @@ -276,7 +276,7 @@ func TestGitCommandGetStashEntries(t *testing.T) { type scenario struct { testName string command func(string, ...string) *exec.Cmd - test func([]StashEntry) + test func([]*StashEntry) } scenarios := []scenario{ @@ -285,7 +285,7 @@ func TestGitCommandGetStashEntries(t *testing.T) { func(string, ...string) *exec.Cmd { return exec.Command("echo") }, - func(entries []StashEntry) { + func(entries []*StashEntry) { assert.Len(t, entries, 0) }, }, @@ -294,8 +294,8 @@ func TestGitCommandGetStashEntries(t *testing.T) { func(string, ...string) *exec.Cmd { return exec.Command("echo", "WIP on add-pkg-commands-test: 55c6af2 increase parallel build\nWIP on master: bb86a3f update github template") }, - func(entries []StashEntry) { - expected := []StashEntry{ + func(entries []*StashEntry) { + expected := []*StashEntry{ { 0, "WIP on add-pkg-commands-test: 55c6af2 increase parallel build", @@ -342,7 +342,7 @@ func TestGitCommandGetStatusFiles(t *testing.T) { type scenario struct { testName string command func(string, ...string) *exec.Cmd - test func([]File) + test func([]*File) } scenarios := []scenario{ @@ -351,7 +351,7 @@ func TestGitCommandGetStatusFiles(t *testing.T) { func(cmd string, args ...string) *exec.Cmd { return exec.Command("echo") }, - func(files []File) { + func(files []*File) { assert.Len(t, files, 0) }, }, @@ -363,10 +363,10 @@ func TestGitCommandGetStatusFiles(t *testing.T) { "MM file1.txt\nA file3.txt\nAM file2.txt\n?? file4.txt", ) }, - func(files []File) { + func(files []*File) { assert.Len(t, files, 4) - expected := []File{ + expected := []*File{ { Name: "file1.txt", HasStagedChanges: true, @@ -464,22 +464,22 @@ func TestGitCommandCommitAmend(t *testing.T) { func TestGitCommandMergeStatusFiles(t *testing.T) { type scenario struct { testName string - oldFiles []File - newFiles []File - test func([]File) + oldFiles []*File + newFiles []*File + test func([]*File) } scenarios := []scenario{ { "Old file and new file are the same", - []File{}, - []File{ + []*File{}, + []*File{ { Name: "new_file.txt", }, }, - func(files []File) { - expected := []File{ + func(files []*File) { + expected := []*File{ { Name: "new_file.txt", }, @@ -491,7 +491,7 @@ func TestGitCommandMergeStatusFiles(t *testing.T) { }, { "Several files to merge, with some identical", - []File{ + []*File{ { Name: "new_file1.txt", }, @@ -502,7 +502,7 @@ func TestGitCommandMergeStatusFiles(t *testing.T) { Name: "new_file3.txt", }, }, - []File{ + []*File{ { Name: "new_file4.txt", }, @@ -513,8 +513,8 @@ func TestGitCommandMergeStatusFiles(t *testing.T) { Name: "new_file1.txt", }, }, - func(files []File) { - expected := []File{ + func(files []*File) { + expected := []*File{ { Name: "new_file1.txt", }, @@ -631,7 +631,7 @@ func TestGitCommandGetCommitsToPush(t *testing.T) { t.Run(s.testName, func(t *testing.T) { gitCmd := newDummyGitCommand() gitCmd.OSCommand.command = s.command - s.test(gitCmd.getCommitsToPush()) + s.test(gitCmd.GetCommitsToPush()) }) } } @@ -1225,7 +1225,7 @@ func TestGitCommandRemoveFile(t *testing.T) { testName string command func() (func(string, ...string) *exec.Cmd, *[][]string) test func(*[][]string, error) - file File + file *File removeFile func(string) error } @@ -1247,7 +1247,7 @@ func TestGitCommandRemoveFile(t *testing.T) { {"reset", "--", "test"}, }) }, - File{ + &File{ Name: "test", HasStagedChanges: true, }, @@ -1270,7 +1270,7 @@ func TestGitCommandRemoveFile(t *testing.T) { assert.EqualError(t, err, "an error occurred when removing file") assert.Len(t, *cmdsCalled, 0) }, - File{ + &File{ Name: "test", Tracked: false, }, @@ -1295,7 +1295,7 @@ func TestGitCommandRemoveFile(t *testing.T) { {"checkout", "--", "test"}, }) }, - File{ + &File{ Name: "test", Tracked: true, HasStagedChanges: false, @@ -1321,7 +1321,7 @@ func TestGitCommandRemoveFile(t *testing.T) { {"checkout", "--", "test"}, }) }, - File{ + &File{ Name: "test", Tracked: true, HasStagedChanges: false, @@ -1348,7 +1348,7 @@ func TestGitCommandRemoveFile(t *testing.T) { {"checkout", "--", "test"}, }) }, - File{ + &File{ Name: "test", Tracked: true, HasStagedChanges: true, @@ -1374,7 +1374,7 @@ func TestGitCommandRemoveFile(t *testing.T) { {"reset", "--", "test"}, }) }, - File{ + &File{ Name: "test", Tracked: false, HasStagedChanges: true, @@ -1398,7 +1398,7 @@ func TestGitCommandRemoveFile(t *testing.T) { assert.NoError(t, err) assert.Len(t, *cmdsCalled, 0) }, - File{ + &File{ Name: "test", Tracked: false, HasStagedChanges: false, @@ -1484,7 +1484,7 @@ func TestGitCommandGetCommits(t *testing.T) { type scenario struct { testName string command func(string, ...string) *exec.Cmd - test func([]Commit) + test func([]*Commit) } scenarios := []scenario{ @@ -1504,7 +1504,7 @@ func TestGitCommandGetCommits(t *testing.T) { return nil }, - func(commits []Commit) { + func(commits []*Commit) { assert.Len(t, commits, 0) }, }, @@ -1524,9 +1524,9 @@ func TestGitCommandGetCommits(t *testing.T) { return nil }, - func(commits []Commit) { + func(commits []*Commit) { assert.Len(t, commits, 2) - assert.EqualValues(t, []Commit{ + assert.EqualValues(t, []*Commit{ { Sha: "8a2bb0e", Name: "commit 1", @@ -1557,7 +1557,7 @@ func TestGitCommandDiff(t *testing.T) { gitCommand := newDummyGitCommand() assert.NoError(t, test.GenerateRepo("lots_of_diffs.sh")) - files := []File{ + files := []*File{ { Name: "deleted_staged", HasStagedChanges: false, diff --git a/pkg/commands/stash_entry.go b/pkg/commands/stash_entry.go new file mode 100644 index 000000000..3886fd4c9 --- /dev/null +++ b/pkg/commands/stash_entry.go @@ -0,0 +1,13 @@ +package commands + +// StashEntry : A git stash entry +type StashEntry struct { + Index int + Name string + DisplayString string +} + +// GetDisplayStrings returns the dispaly string of branch +func (s *StashEntry) GetDisplayStrings() []string { + return []string{s.DisplayString} +} diff --git a/pkg/git/branch_list_builder.go b/pkg/git/branch_list_builder.go index 651b684f5..151e5b0b4 100644 --- a/pkg/git/branch_list_builder.go +++ b/pkg/git/branch_list_builder.go @@ -34,7 +34,7 @@ func NewBranchListBuilder(log *logrus.Entry, gitCommand *commands.GitCommand) (* }, nil } -func (b *BranchListBuilder) obtainCurrentBranch() commands.Branch { +func (b *BranchListBuilder) obtainCurrentBranch() *commands.Branch { // I used go-git for this, but that breaks if you've just done a git init, // even though you're on 'master' branchName, err := b.GitCommand.OSCommand.RunCommandWithOutput("git symbolic-ref --short HEAD") @@ -44,11 +44,11 @@ func (b *BranchListBuilder) obtainCurrentBranch() commands.Branch { panic(err.Error()) } } - return commands.Branch{Name: strings.TrimSpace(branchName), Recency: " *"} + return &commands.Branch{Name: strings.TrimSpace(branchName), Recency: " *"} } -func (b *BranchListBuilder) obtainReflogBranches() []commands.Branch { - branches := make([]commands.Branch, 0) +func (b *BranchListBuilder) obtainReflogBranches() []*commands.Branch { + branches := make([]*commands.Branch, 0) rawString, err := b.GitCommand.OSCommand.RunCommandWithOutput("git reflog -n100 --pretty='%cr|%gs' --grep-reflog='checkout: moving' HEAD") if err != nil { return branches @@ -58,14 +58,14 @@ func (b *BranchListBuilder) obtainReflogBranches() []commands.Branch { for _, line := range branchLines { timeNumber, timeUnit, branchName := branchInfoFromLine(line) timeUnit = abbreviatedTimeUnit(timeUnit) - branch := commands.Branch{Name: branchName, Recency: timeNumber + timeUnit} + branch := &commands.Branch{Name: branchName, Recency: timeNumber + timeUnit} branches = append(branches, branch) } return branches } -func (b *BranchListBuilder) obtainSafeBranches() []commands.Branch { - branches := make([]commands.Branch, 0) +func (b *BranchListBuilder) obtainSafeBranches() []*commands.Branch { + branches := make([]*commands.Branch, 0) bIter, err := b.GitCommand.Repo.Branches() if err != nil { @@ -73,14 +73,14 @@ func (b *BranchListBuilder) obtainSafeBranches() []commands.Branch { } err = bIter.ForEach(func(b *plumbing.Reference) error { name := b.Name().Short() - branches = append(branches, commands.Branch{Name: name}) + branches = append(branches, &commands.Branch{Name: name}) return nil }) return branches } -func (b *BranchListBuilder) appendNewBranches(finalBranches, newBranches, existingBranches []commands.Branch, included bool) []commands.Branch { +func (b *BranchListBuilder) appendNewBranches(finalBranches, newBranches, existingBranches []*commands.Branch, included bool) []*commands.Branch { for _, newBranch := range newBranches { if included == branchIncluded(newBranch.Name, existingBranches) { finalBranches = append(finalBranches, newBranch) @@ -89,7 +89,7 @@ func (b *BranchListBuilder) appendNewBranches(finalBranches, newBranches, existi return finalBranches } -func sanitisedReflogName(reflogBranch commands.Branch, safeBranches []commands.Branch) string { +func sanitisedReflogName(reflogBranch *commands.Branch, safeBranches []*commands.Branch) string { for _, safeBranch := range safeBranches { if strings.ToLower(safeBranch.Name) == strings.ToLower(reflogBranch.Name) { return safeBranch.Name @@ -99,15 +99,15 @@ func sanitisedReflogName(reflogBranch commands.Branch, safeBranches []commands.B } // Build the list of branches for the current repo -func (b *BranchListBuilder) Build() []commands.Branch { - branches := make([]commands.Branch, 0) +func (b *BranchListBuilder) Build() []*commands.Branch { + branches := make([]*commands.Branch, 0) head := b.obtainCurrentBranch() safeBranches := b.obtainSafeBranches() if len(safeBranches) == 0 { return append(branches, head) } reflogBranches := b.obtainReflogBranches() - reflogBranches = uniqueByName(append([]commands.Branch{head}, reflogBranches...)) + reflogBranches = uniqueByName(append([]*commands.Branch{head}, reflogBranches...)) for i, reflogBranch := range reflogBranches { reflogBranches[i].Name = sanitisedReflogName(reflogBranch, safeBranches) } @@ -118,7 +118,7 @@ func (b *BranchListBuilder) Build() []commands.Branch { return branches } -func branchIncluded(branchName string, branches []commands.Branch) bool { +func branchIncluded(branchName string, branches []*commands.Branch) bool { for _, existingBranch := range branches { if strings.ToLower(existingBranch.Name) == strings.ToLower(branchName) { return true @@ -127,8 +127,8 @@ func branchIncluded(branchName string, branches []commands.Branch) bool { return false } -func uniqueByName(branches []commands.Branch) []commands.Branch { - finalBranches := make([]commands.Branch, 0) +func uniqueByName(branches []*commands.Branch) []*commands.Branch { + finalBranches := make([]*commands.Branch, 0) for _, branch := range branches { if branchIncluded(branch.Name, finalBranches) { continue diff --git a/pkg/gui/branches_panel.go b/pkg/gui/branches_panel.go index 26c3c5618..0f66533b1 100644 --- a/pkg/gui/branches_panel.go +++ b/pkg/gui/branches_panel.go @@ -7,6 +7,7 @@ import ( "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazygit/pkg/commands" "github.com/jesseduffield/lazygit/pkg/git" + "github.com/jesseduffield/lazygit/pkg/utils" ) func (gui *Gui) handleBranchPress(g *gocui.Gui, v *gocui.View) error { @@ -109,7 +110,7 @@ func (gui *Gui) handleMerge(g *gocui.Gui, v *gocui.View) error { return nil } -func (gui *Gui) getSelectedBranch(v *gocui.View) commands.Branch { +func (gui *Gui) getSelectedBranch(v *gocui.View) *commands.Branch { lineNumber := gui.getItemPosition(v) return gui.State.Branches[lineNumber] } @@ -151,10 +152,15 @@ func (gui *Gui) refreshBranches(g *gocui.Gui) error { return err } gui.State.Branches = builder.Build() + v.Clear() - for _, branch := range gui.State.Branches { - fmt.Fprintln(v, branch.GetDisplayString()) + list, err := utils.RenderList(gui.State.Branches) + if err != nil { + return err } + + fmt.Fprint(v, list) + gui.resetOrigin(v) return gui.refreshStatus(g) }) diff --git a/pkg/gui/commits_panel.go b/pkg/gui/commits_panel.go index 075d66c83..7c09559ff 100644 --- a/pkg/gui/commits_panel.go +++ b/pkg/gui/commits_panel.go @@ -2,10 +2,11 @@ package gui import ( "errors" + "fmt" - "github.com/fatih/color" "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazygit/pkg/commands" + "github.com/jesseduffield/lazygit/pkg/utils" ) func (gui *Gui) refreshCommits(g *gocui.Gui) error { @@ -15,20 +16,14 @@ func (gui *Gui) refreshCommits(g *gocui.Gui) error { if err != nil { panic(err) } + v.Clear() - red := color.New(color.FgRed) - yellow := color.New(color.FgYellow) - white := color.New(color.FgWhite) - shaColor := white - for _, commit := range gui.State.Commits { - if commit.Pushed { - shaColor = red - } else { - shaColor = yellow - } - shaColor.Fprint(v, commit.Sha+" ") - white.Fprintln(v, commit.Name) + list, err := utils.RenderList(gui.State.Commits) + if err != nil { + return err } + fmt.Fprint(v, list) + gui.refreshStatus(g) if g.CurrentView().Name() == "commits" { gui.handleCommitSelect(g, v) @@ -99,7 +94,7 @@ func (gui *Gui) handleCommitSquashDown(g *gocui.Gui, v *gocui.View) error { } // TODO: move to files panel -func (gui *Gui) anyUnStagedChanges(files []commands.File) bool { +func (gui *Gui) anyUnStagedChanges(files []*commands.File) bool { for _, file := range files { if file.Tracked && file.HasUnstagedChanges { return true @@ -161,13 +156,13 @@ func (gui *Gui) handleRenameCommitEditor(g *gocui.Gui, v *gocui.View) error { return nil } -func (gui *Gui) getSelectedCommit(g *gocui.Gui) (commands.Commit, error) { +func (gui *Gui) getSelectedCommit(g *gocui.Gui) (*commands.Commit, error) { v, err := g.View("commits") if err != nil { panic(err) } if len(gui.State.Commits) == 0 { - return commands.Commit{}, errors.New(gui.Tr.SLocalize("NoCommitsThisBranch")) + return &commands.Commit{}, errors.New(gui.Tr.SLocalize("NoCommitsThisBranch")) } lineNumber := gui.getItemPosition(v) if lineNumber > len(gui.State.Commits)-1 { diff --git a/pkg/gui/files_panel.go b/pkg/gui/files_panel.go index bfcc938bb..574e6bc1c 100644 --- a/pkg/gui/files_panel.go +++ b/pkg/gui/files_panel.go @@ -7,16 +7,17 @@ import ( // "strings" + "fmt" "strings" - "github.com/fatih/color" "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazygit/pkg/commands" + "github.com/jesseduffield/lazygit/pkg/utils" ) -func (gui *Gui) stagedFiles() []commands.File { +func (gui *Gui) stagedFiles() []*commands.File { files := gui.State.Files - result := make([]commands.File, 0) + result := make([]*commands.File, 0) for _, file := range files { if file.HasStagedChanges { result = append(result, file) @@ -25,9 +26,9 @@ func (gui *Gui) stagedFiles() []commands.File { return result } -func (gui *Gui) trackedFiles() []commands.File { +func (gui *Gui) trackedFiles() []*commands.File { files := gui.State.Files - result := make([]commands.File, 0) + result := make([]*commands.File, 0) for _, file := range files { if file.Tracked { result = append(result, file) @@ -116,9 +117,9 @@ func (gui *Gui) handleAddPatch(g *gocui.Gui, v *gocui.View) error { return gui.Errors.ErrSubProcess } -func (gui *Gui) getSelectedFile(g *gocui.Gui) (commands.File, error) { +func (gui *Gui) getSelectedFile(g *gocui.Gui) (*commands.File, error) { if len(gui.State.Files) == 0 { - return commands.File{}, gui.Errors.ErrNoFiles + return &commands.File{}, gui.Errors.ErrNoFiles } filesView, err := g.View("files") if err != nil { @@ -184,7 +185,9 @@ func (gui *Gui) handleFileSelect(g *gocui.Gui, v *gocui.View) error { gui.renderString(g, "main", gui.Tr.SLocalize("NoChangedFiles")) return gui.renderfilesOptions(g, nil) } - gui.renderfilesOptions(g, &file) + if err := gui.renderfilesOptions(g, file); err != nil { + return err + } var content string if file.HasMergeConflicts { return gui.refreshMergePanel(g) @@ -275,24 +278,6 @@ func (gui *Gui) updateHasMergeConflictStatus() error { return nil } -func (gui *Gui) renderFile(file commands.File, filesView *gocui.View) { - // potentially inefficient to be instantiating these color - // objects with each render - red := color.New(color.FgRed) - green := color.New(color.FgGreen) - if !file.Tracked && !file.HasStagedChanges { - red.Fprintln(filesView, file.DisplayString) - return - } - green.Fprint(filesView, file.DisplayString[0:1]) - red.Fprint(filesView, file.DisplayString[1:3]) - if file.HasUnstagedChanges { - red.Fprintln(filesView, file.Name) - } else { - green.Fprintln(filesView, file.Name) - } -} - func (gui *Gui) catSelectedFile(g *gocui.Gui) (string, error) { item, err := gui.getSelectedFile(g) if err != nil { @@ -318,10 +303,14 @@ func (gui *Gui) refreshFiles(g *gocui.Gui) error { return err } gui.refreshStateFiles() + filesView.Clear() - for _, file := range gui.State.Files { - gui.renderFile(file, filesView) + list, err := utils.RenderList(gui.State.Files) + if err != nil { + return err } + fmt.Fprint(filesView, list) + gui.correctCursor(filesView) if filesView == g.CurrentView() { gui.handleFileSelect(g, filesView) diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index e3cc61529..8a2aaea81 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -71,10 +71,10 @@ type Gui struct { } type guiState struct { - Files []commands.File - Branches []commands.Branch - Commits []commands.Commit - StashEntries []commands.StashEntry + Files []*commands.File + Branches []*commands.Branch |