mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-02-09 13:47:11 +02:00
more generics
This commit is contained in:
parent
eda8f4a5d4
commit
bf4f06ab4e
2
go.mod
2
go.mod
@ -14,7 +14,7 @@ require (
|
||||
github.com/gookit/color v1.4.2
|
||||
github.com/imdario/mergo v0.3.11
|
||||
github.com/integrii/flaggy v1.4.0
|
||||
github.com/jesseduffield/generics v0.0.0-20220319042131-63614a800d5f
|
||||
github.com/jesseduffield/generics v0.0.0-20220319062156-fa5cb8bde518
|
||||
github.com/jesseduffield/go-git/v5 v5.1.2-0.20201006095850-341962be15a4
|
||||
github.com/jesseduffield/gocui v0.3.1-0.20220227022729-69f0c798eec8
|
||||
github.com/jesseduffield/minimal/gitignore v0.3.3-0.20211018110810-9cde264e6b1e
|
||||
|
4
go.sum
4
go.sum
@ -66,8 +66,8 @@ github.com/integrii/flaggy v1.4.0 h1:A1x7SYx4jqu5NSrY14z8Z+0UyX2S5ygfJJrfolWR3zM
|
||||
github.com/integrii/flaggy v1.4.0/go.mod h1:tnTxHeTJbah0gQ6/K0RW0J7fMUBk9MCF5blhm43LNpI=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||
github.com/jesseduffield/generics v0.0.0-20220319042131-63614a800d5f h1:VZkNxrfkR344djm4Ju7QuKLXxZlaaOaNCrAWVRc1gvU=
|
||||
github.com/jesseduffield/generics v0.0.0-20220319042131-63614a800d5f/go.mod h1:+LLj9/WUPAP8LqCchs7P+7X0R98HiFujVFANdNaxhGk=
|
||||
github.com/jesseduffield/generics v0.0.0-20220319062156-fa5cb8bde518 h1:scclO0fuRMsIdYr6Gg+9LS1S1ZO93tHKQSbErWQWQ4s=
|
||||
github.com/jesseduffield/generics v0.0.0-20220319062156-fa5cb8bde518/go.mod h1:+LLj9/WUPAP8LqCchs7P+7X0R98HiFujVFANdNaxhGk=
|
||||
github.com/jesseduffield/go-git/v5 v5.1.2-0.20201006095850-341962be15a4 h1:GOQrmaE8i+KEdB8NzAegKYd4tPn/inM0I1uo0NXFerg=
|
||||
github.com/jesseduffield/go-git/v5 v5.1.2-0.20201006095850-341962be15a4/go.mod h1:nGNEErzf+NRznT+N2SWqmHnDnF9aLgANB1CUNEan09o=
|
||||
github.com/jesseduffield/gocui v0.3.1-0.20220227022729-69f0c798eec8 h1:9N08i5kjvOfkzMj6THmIM110wPTQLdVYEOHMHT2DFiI=
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/jesseduffield/generics/maps"
|
||||
"github.com/jesseduffield/generics/slices"
|
||||
"github.com/jesseduffield/lazygit/pkg/app"
|
||||
"github.com/jesseduffield/lazygit/pkg/config"
|
||||
@ -174,11 +175,12 @@ outer:
|
||||
bindings []*types.Binding
|
||||
}
|
||||
|
||||
groupedBindings := make([]groupedBindingsType, 0, len(contextAndViewBindingMap))
|
||||
|
||||
for contextAndView, contextBindings := range contextAndViewBindingMap {
|
||||
groupedBindings = append(groupedBindings, groupedBindingsType{contextAndView: contextAndView, bindings: contextBindings})
|
||||
}
|
||||
groupedBindings := maps.MapToSlice(
|
||||
contextAndViewBindingMap,
|
||||
func(contextAndView contextAndViewType, contextBindings []*types.Binding) groupedBindingsType {
|
||||
return groupedBindingsType{contextAndView: contextAndView, bindings: contextBindings}
|
||||
},
|
||||
)
|
||||
|
||||
slices.SortFunc(groupedBindings, func(a, b groupedBindingsType) bool {
|
||||
first := a.contextAndView
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/go-errors/errors"
|
||||
"github.com/jesseduffield/generics/slices"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/loaders"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||
@ -46,10 +47,9 @@ func (self *WorkingTreeCommands) StageFile(path string) error {
|
||||
}
|
||||
|
||||
func (self *WorkingTreeCommands) StageFiles(paths []string) error {
|
||||
quotedPaths := make([]string, len(paths))
|
||||
for i, path := range paths {
|
||||
quotedPaths[i] = self.cmd.Quote(path)
|
||||
}
|
||||
quotedPaths := slices.Map(paths, func(path string) string {
|
||||
return self.cmd.Quote(path)
|
||||
})
|
||||
return self.cmd.New(fmt.Sprintf("git add -- %s", strings.Join(quotedPaths, " "))).Run()
|
||||
}
|
||||
|
||||
|
@ -66,13 +66,13 @@ outer:
|
||||
if strings.EqualFold(reflogBranch.Name, branch.Name) {
|
||||
branch.Recency = reflogBranch.Recency
|
||||
branchesWithRecency = append(branchesWithRecency, branch)
|
||||
branches = append(branches[0:j], branches[j+1:]...)
|
||||
branches = slices.Remove(branches, j)
|
||||
continue outer
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
branches = append(branchesWithRecency, branches...)
|
||||
branches = slices.Prepend(branches, branchesWithRecency...)
|
||||
|
||||
foundHead := false
|
||||
for i, branch := range branches {
|
||||
@ -159,7 +159,7 @@ func (self *BranchLoader) obtainBranches() []*models.Branch {
|
||||
trimmedOutput := strings.TrimSpace(output)
|
||||
outputLines := strings.Split(trimmedOutput, "\n")
|
||||
|
||||
branches := slices.FilterMap(outputLines, func(line string) (*models.Branch, bool) {
|
||||
return slices.FilterMap(outputLines, func(line string) (*models.Branch, bool) {
|
||||
if line == "" {
|
||||
return nil, false
|
||||
}
|
||||
@ -174,8 +174,6 @@ func (self *BranchLoader) obtainBranches() []*models.Branch {
|
||||
|
||||
return obtainBranch(split), true
|
||||
})
|
||||
|
||||
return branches
|
||||
}
|
||||
|
||||
// TODO: only look at the new reflog commits, and otherwise store the recencies in
|
||||
@ -184,17 +182,21 @@ func (self *BranchLoader) obtainReflogBranches(reflogCommits []*models.Commit) [
|
||||
foundBranches := set.New[string]()
|
||||
re := regexp.MustCompile(`checkout: moving from ([\S]+) to ([\S]+)`)
|
||||
reflogBranches := make([]*models.Branch, 0, len(reflogCommits))
|
||||
|
||||
for _, commit := range reflogCommits {
|
||||
if match := re.FindStringSubmatch(commit.Name); len(match) == 3 {
|
||||
recency := utils.UnixToTimeAgo(commit.UnixTimestamp)
|
||||
for _, branchName := range match[1:] {
|
||||
if !foundBranches.Includes(branchName) {
|
||||
foundBranches.Add(branchName)
|
||||
reflogBranches = append(reflogBranches, &models.Branch{
|
||||
Recency: recency,
|
||||
Name: branchName,
|
||||
})
|
||||
}
|
||||
match := re.FindStringSubmatch(commit.Name)
|
||||
if len(match) != 3 {
|
||||
continue
|
||||
}
|
||||
|
||||
recency := utils.UnixToTimeAgo(commit.UnixTimestamp)
|
||||
for _, branchName := range match[1:] {
|
||||
if !foundBranches.Includes(branchName) {
|
||||
foundBranches.Add(branchName)
|
||||
reflogBranches = append(reflogBranches, &models.Branch{
|
||||
Recency: recency,
|
||||
Name: branchName,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,9 +4,11 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/jesseduffield/generics/slices"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||
"github.com/jesseduffield/lazygit/pkg/common"
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
type CommitFileLoader struct {
|
||||
@ -33,25 +35,22 @@ func (self *CommitFileLoader) GetFilesInDiff(from string, to string, reverse boo
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return self.getCommitFilesFromFilenames(filenames), nil
|
||||
return getCommitFilesFromFilenames(filenames), nil
|
||||
}
|
||||
|
||||
// filenames string is something like "file1\nfile2\nfile3"
|
||||
func (self *CommitFileLoader) getCommitFilesFromFilenames(filenames string) []*models.CommitFile {
|
||||
commitFiles := make([]*models.CommitFile, 0)
|
||||
|
||||
// filenames string is something like "MM\x00file1\x00MU\x00file2\x00AA\x00file3\x00"
|
||||
// so we need to split it by the null character and then map each status-name pair to a commit file
|
||||
func getCommitFilesFromFilenames(filenames string) []*models.CommitFile {
|
||||
lines := strings.Split(strings.TrimRight(filenames, "\x00"), "\x00")
|
||||
n := len(lines)
|
||||
for i := 0; i < n-1; i += 2 {
|
||||
// typical result looks like 'A my_file' meaning my_file was added
|
||||
changeStatus := lines[i]
|
||||
name := lines[i+1]
|
||||
|
||||
commitFiles = append(commitFiles, &models.CommitFile{
|
||||
Name: name,
|
||||
ChangeStatus: changeStatus,
|
||||
})
|
||||
if len(lines) == 1 {
|
||||
return []*models.CommitFile{}
|
||||
}
|
||||
|
||||
return commitFiles
|
||||
// typical result looks like 'A my_file' meaning my_file was added
|
||||
return slices.Map(lo.Chunk(lines, 2), func(chunk []string) *models.CommitFile {
|
||||
return &models.CommitFile{
|
||||
ChangeStatus: chunk[0],
|
||||
Name: chunk[1],
|
||||
}
|
||||
})
|
||||
}
|
||||
|
71
pkg/commands/loaders/commit_files_test.go
Normal file
71
pkg/commands/loaders/commit_files_test.go
Normal file
@ -0,0 +1,71 @@
|
||||
package loaders
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGetCommitFilesFromFilenames(t *testing.T) {
|
||||
tests := []struct {
|
||||
testName string
|
||||
input string
|
||||
output []*models.CommitFile
|
||||
}{
|
||||
{
|
||||
testName: "no files",
|
||||
input: "",
|
||||
output: []*models.CommitFile{},
|
||||
},
|
||||
{
|
||||
testName: "one file",
|
||||
input: "MM\x00Myfile\x00",
|
||||
output: []*models.CommitFile{
|
||||
{
|
||||
Name: "Myfile",
|
||||
ChangeStatus: "MM",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
testName: "two files",
|
||||
input: "MM\x00Myfile\x00M \x00MyOtherFile\x00",
|
||||
output: []*models.CommitFile{
|
||||
{
|
||||
Name: "Myfile",
|
||||
ChangeStatus: "MM",
|
||||
},
|
||||
{
|
||||
Name: "MyOtherFile",
|
||||
ChangeStatus: "M ",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
testName: "three files",
|
||||
input: "MM\x00Myfile\x00M \x00MyOtherFile\x00 M\x00YetAnother\x00",
|
||||
output: []*models.CommitFile{
|
||||
{
|
||||
Name: "Myfile",
|
||||
ChangeStatus: "MM",
|
||||
},
|
||||
{
|
||||
Name: "MyOtherFile",
|
||||
ChangeStatus: "M ",
|
||||
},
|
||||
{
|
||||
Name: "YetAnother",
|
||||
ChangeStatus: " M",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.testName, func(t *testing.T) {
|
||||
result := getCommitFilesFromFilenames(test.input)
|
||||
assert.Equal(t, test.output, result)
|
||||
})
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/jesseduffield/generics/slices"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/types/enums"
|
||||
@ -200,10 +201,9 @@ func (self *CommitLoader) getHydratedRebasingCommits(rebaseMode enums.RebaseMode
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
commitShas := make([]string, len(commits))
|
||||
for i, commit := range commits {
|
||||
commitShas[i] = commit.Sha
|
||||
}
|
||||
commitShas := slices.Map(commits, func(commit *models.Commit) string {
|
||||
return commit.Sha
|
||||
})
|
||||
|
||||
// note that we're not filtering these as we do non-rebasing commits just because
|
||||
// I suspect that will cause some damage
|
||||
|
@ -11,24 +11,6 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func NewDummyCommitLoader() *CommitLoader {
|
||||
cmn := utils.NewDummyCommon()
|
||||
|
||||
return &CommitLoader{
|
||||
Common: cmn,
|
||||
cmd: nil,
|
||||
getCurrentBranchName: func() (string, string, error) { return "master", "master", nil },
|
||||
getRebaseMode: func() (enums.RebaseMode, error) { return enums.REBASE_MODE_NONE, nil },
|
||||
dotGitDir: ".git",
|
||||
readFile: func(filename string) ([]byte, error) {
|
||||
return []byte(""), nil
|
||||
},
|
||||
walkFiles: func(root string, fn filepath.WalkFunc) error {
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
const commitsOutput = `0eea75e8c631fba6b58135697835d58ba4c18dbc|1640826609|Jesse Duffield| (HEAD -> better-tests)|b21997d6b4cbdf84b149|better typing for rebase mode
|
||||
b21997d6b4cbdf84b149d8e6a2c4d06a8e9ec164|1640824515|Jesse Duffield| (origin/better-tests)|e94e8fc5b6fab4cb755f|fix logging
|
||||
e94e8fc5b6fab4cb755f29f1bdb3ee5e001df35c|1640823749|Jesse Duffield||d8084cd558925eb7c9c3|refactor
|
||||
|
@ -1,8 +1,7 @@
|
||||
package loaders
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/jesseduffield/generics/slices"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||
"github.com/jesseduffield/lazygit/pkg/common"
|
||||
@ -27,25 +26,18 @@ func NewTagLoader(
|
||||
func (self *TagLoader) GetTags() ([]*models.Tag, error) {
|
||||
// get remote branches, sorted by creation date (descending)
|
||||
// see: https://git-scm.com/docs/git-tag#Documentation/git-tag.txt---sortltkeygt
|
||||
remoteBranchesStr, err := self.cmd.New(`git tag --list --sort=-creatordate`).DontLog().RunWithOutput()
|
||||
tagsOutput, err := self.cmd.New(`git tag --list --sort=-creatordate`).DontLog().RunWithOutput()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
content := utils.TrimTrailingNewline(remoteBranchesStr)
|
||||
if content == "" {
|
||||
return nil, nil
|
||||
}
|
||||
split := utils.SplitLines(tagsOutput)
|
||||
|
||||
split := strings.Split(content, "\n")
|
||||
|
||||
// first step is to get our remotes from go-git
|
||||
tags := make([]*models.Tag, len(split))
|
||||
for i, tagName := range split {
|
||||
tags[i] = &models.Tag{
|
||||
tags := slices.Map(split, func(tagName string) *models.Tag {
|
||||
return &models.Tag{
|
||||
Name: tagName,
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return tags, nil
|
||||
}
|
||||
|
68
pkg/commands/loaders/tags_test.go
Normal file
68
pkg/commands/loaders/tags_test.go
Normal file
@ -0,0 +1,68 @@
|
||||
package loaders
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
const tagsOutput = `v0.34
|
||||
v0.33
|
||||
v0.32.2
|
||||
v0.32.1
|
||||
v0.32
|
||||
testtag
|
||||
`
|
||||
|
||||
func TestGetTags(t *testing.T) {
|
||||
type scenario struct {
|
||||
testName string
|
||||
runner *oscommands.FakeCmdObjRunner
|
||||
expectedTags []*models.Tag
|
||||
expectedError error
|
||||
}
|
||||
|
||||
scenarios := []scenario{
|
||||
{
|
||||
testName: "should return no tags if there are none",
|
||||
runner: oscommands.NewFakeRunner(t).
|
||||
Expect(`git tag --list --sort=-creatordate`, "", nil),
|
||||
expectedTags: []*models.Tag{},
|
||||
expectedError: nil,
|
||||
},
|
||||
{
|
||||
testName: "should return tags if present",
|
||||
runner: oscommands.NewFakeRunner(t).
|
||||
Expect(`git tag --list --sort=-creatordate`, tagsOutput, nil),
|
||||
expectedTags: []*models.Tag{
|
||||
{Name: "v0.34"},
|
||||
{Name: "v0.33"},
|
||||
{Name: "v0.32.2"},
|
||||
{Name: "v0.32.1"},
|
||||
{Name: "v0.32"},
|
||||
{Name: "testtag"},
|
||||
},
|
||||
expectedError: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, scenario := range scenarios {
|
||||
scenario := scenario
|
||||
t.Run(scenario.testName, func(t *testing.T) {
|
||||
loader := &TagLoader{
|
||||
Common: utils.NewDummyCommon(),
|
||||
cmd: oscommands.NewDummyCmdObjBuilder(scenario.runner),
|
||||
}
|
||||
|
||||
tags, err := loader.GetTags()
|
||||
|
||||
assert.Equal(t, scenario.expectedTags, tags)
|
||||
assert.Equal(t, scenario.expectedError, err)
|
||||
|
||||
scenario.runner.CheckForMissingCalls()
|
||||
})
|
||||
}
|
||||
}
|
@ -12,6 +12,7 @@ import (
|
||||
"github.com/go-errors/errors"
|
||||
|
||||
"github.com/atotto/clipboard"
|
||||
"github.com/jesseduffield/generics/slices"
|
||||
"github.com/jesseduffield/lazygit/pkg/common"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
)
|
||||
@ -173,15 +174,11 @@ func (c *OSCommand) FileExists(path string) (bool, error) {
|
||||
|
||||
// PipeCommands runs a heap of commands and pipes their inputs/outputs together like A | B | C
|
||||
func (c *OSCommand) PipeCommands(commandStrings ...string) error {
|
||||
cmds := make([]*exec.Cmd, len(commandStrings))
|
||||
logCmdStr := ""
|
||||
for i, str := range commandStrings {
|
||||
if i > 0 {
|
||||
logCmdStr += " | "
|
||||
}
|
||||
logCmdStr += str
|
||||
cmds[i] = c.Cmd.New(str).GetCmd()
|
||||
}
|
||||
cmds := slices.Map(commandStrings, func(cmdString string) *exec.Cmd {
|
||||
return c.Cmd.New(cmdString).GetCmd()
|
||||
})
|
||||
|
||||
logCmdStr := strings.Join(commandStrings, " | ")
|
||||
c.LogCommand(logCmdStr, true)
|
||||
|
||||
for i := 0; i < len(cmds)-1; i++ {
|
||||
|
@ -4,6 +4,8 @@ import (
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/jesseduffield/generics/maps"
|
||||
"github.com/jesseduffield/generics/slices"
|
||||
"github.com/samber/lo"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
@ -72,8 +74,9 @@ func (p *PatchManager) Start(from, to string, reverse bool, canRebase bool) {
|
||||
func (p *PatchManager) addFileWhole(info *fileInfo) {
|
||||
info.mode = WHOLE
|
||||
lineCount := len(strings.Split(info.diff, "\n"))
|
||||
info.includedLineIndices = make([]int, lineCount)
|
||||
// add every line index
|
||||
// TODO: add tests and then use lo.Range to simplify
|
||||
info.includedLineIndices = make([]int, lineCount)
|
||||
for i := 0; i < lineCount; i++ {
|
||||
info.includedLineIndices[i] = i
|
||||
}
|
||||
@ -192,21 +195,15 @@ func (p *PatchManager) RenderPatchForFile(filename string, plain bool, reverse b
|
||||
|
||||
func (p *PatchManager) renderEachFilePatch(plain bool) []string {
|
||||
// sort files by name then iterate through and render each patch
|
||||
filenames := make([]string, len(p.fileInfoMap))
|
||||
index := 0
|
||||
for filename := range p.fileInfoMap {
|
||||
filenames[index] = filename
|
||||
index++
|
||||
}
|
||||
filenames := maps.Keys(p.fileInfoMap)
|
||||
|
||||
sort.Strings(filenames)
|
||||
output := []string{}
|
||||
for _, filename := range filenames {
|
||||
patch := p.RenderPatchForFile(filename, plain, false, true)
|
||||
if patch != "" {
|
||||
output = append(output, patch)
|
||||
}
|
||||
}
|
||||
patches := slices.Map(filenames, func(filename string) string {
|
||||
return p.RenderPatchForFile(filename, plain, false, true)
|
||||
})
|
||||
output := slices.Filter(patches, func(patch string) bool {
|
||||
return patch != ""
|
||||
})
|
||||
|
||||
return output
|
||||
}
|
||||
|
@ -4,9 +4,9 @@ import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/jesseduffield/generics/slices"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/style"
|
||||
"github.com/jesseduffield/lazygit/pkg/theme"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
"github.com/samber/lo"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
@ -184,16 +184,21 @@ func parsePatch(patch string) ([]int, []int, []*PatchLine) {
|
||||
|
||||
// Render returns the coloured string of the diff with any selected lines highlighted
|
||||
func (p *PatchParser) Render(firstLineIndex int, lastLineIndex int, incLineIndices []int) string {
|
||||
renderedLines := make([]string, len(p.PatchLines))
|
||||
for index, patchLine := range p.PatchLines {
|
||||
selected := index >= firstLineIndex && index <= lastLineIndex
|
||||
included := lo.Contains(incLineIndices, index)
|
||||
renderedLines[index] = patchLine.render(selected, included)
|
||||
}
|
||||
result := strings.Join(renderedLines, "\n")
|
||||
if strings.TrimSpace(utils.Decolorise(result)) == "" {
|
||||
contentToDisplay := slices.Some(p.PatchLines, func(line *PatchLine) bool {
|
||||
return line.Content != ""
|
||||
})
|
||||
if !contentToDisplay {
|
||||
return ""
|
||||
}
|
||||
|
||||
renderedLines := lo.Map(p.PatchLines, func(patchLine *PatchLine, index int) string {
|
||||
selected := index >= firstLineIndex && index <= lastLineIndex
|
||||
included := lo.Contains(incLineIndices, index)
|
||||
return patchLine.render(selected, included)
|
||||
})
|
||||
|
||||
result := strings.Join(renderedLines, "\n")
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@ -202,10 +207,9 @@ func (p *PatchParser) Render(firstLineIndex int, lastLineIndex int, incLineIndic
|
||||
func (p *PatchParser) PlainRenderLines(firstLineIndex, lastLineIndex int) string {
|
||||
linesToCopy := p.PatchLines[firstLineIndex : lastLineIndex+1]
|
||||
|
||||
renderedLines := make([]string, len(linesToCopy))
|
||||
for index, line := range linesToCopy {
|
||||
renderedLines[index] = line.Content
|
||||
}
|
||||
renderedLines := slices.Map(linesToCopy, func(line *PatchLine) string {
|
||||
return line.Content
|
||||
})
|
||||
|
||||
return strings.Join(renderedLines, "\n")
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/jesseduffield/generics/maps"
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
@ -231,10 +232,9 @@ func (gui *Gui) activateContext(c types.Context, opts ...types.OnFocusOpts) erro
|
||||
}
|
||||
|
||||
func (gui *Gui) optionsMapToString(optionsMap map[string]string) string {
|
||||
optionsArray := make([]string, 0)
|
||||
for key, description := range optionsMap {
|
||||
optionsArray = append(optionsArray, key+": "+description)
|
||||
}
|
||||
optionsArray := maps.MapToSlice(optionsMap, func(key string, description string) string {
|
||||
return key + ": " + description
|
||||
})
|
||||
sort.Strings(optionsArray)
|
||||
return strings.Join(optionsArray, ", ")
|
||||
}
|
||||
|
@ -38,13 +38,14 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
|
||||
focus bool
|
||||
}{
|
||||
{
|
||||
testName: "no commits",
|
||||
commits: []*models.Commit{},
|
||||
startIdx: 0,
|
||||
length: 1,
|
||||
showGraph: false,
|
||||
bisectInfo: git_commands.NewNullBisectInfo(),
|
||||
expected: "",
|
||||
testName: "no commits",
|
||||
commits: []*models.Commit{},
|
||||
startIdx: 0,
|
||||
length: 1,
|
||||
showGraph: false,
|
||||
bisectInfo: git_commands.NewNullBisectInfo(),
|
||||
cherryPickedCommitShaSet: set.New[string](),
|
||||
expected: "",
|
||||
},
|
||||
{
|
||||
testName: "some commits",
|
||||
@ -52,10 +53,11 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
|
||||
{Name: "commit1", Sha: "sha1"},
|
||||
{Name: "commit2", Sha: "sha2"},
|
||||
},
|
||||
startIdx: 0,
|
||||
length: 2,
|
||||
showGraph: false,
|
||||
bisectInfo: git_commands.NewNullBisectInfo(),
|
||||
startIdx: 0,
|
||||
length: 2,
|
||||
showGraph: false,
|
||||
bisectInfo: git_commands.NewNullBisectInfo(),
|
||||
cherryPickedCommitShaSet: set.New[string](),
|
||||
expected: formatExpected(`
|
||||
sha1 commit1
|
||||
sha2 commit2
|
||||
@ -70,10 +72,11 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
|
||||
{Name: "commit4", Sha: "sha4", Parents: []string{"sha5"}},
|
||||
{Name: "commit5", Sha: "sha5", Parents: []string{"sha7"}},
|
||||
},
|
||||
startIdx: 0,
|
||||
length: 5,
|
||||
showGraph: true,
|
||||
bisectInfo: git_commands.NewNullBisectInfo(),
|
||||
startIdx: 0,
|
||||
length: 5,
|
||||
showGraph: true,
|
||||
bisectInfo: git_commands.NewNullBisectInfo(),
|
||||
cherryPickedCommitShaSet: set.New[string](),
|
||||
expected: formatExpected(`
|
||||
sha1 ⏣─╮ commit1
|
||||
sha2 ◯ │ commit2
|
||||
@ -91,10 +94,11 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
|
||||
{Name: "commit4", Sha: "sha4", Parents: []string{"sha5"}},
|
||||
{Name: "commit5", Sha: "sha5", Parents: []string{"sha7"}},
|
||||
},
|
||||
startIdx: 0,
|
||||
length: 5,
|
||||
showGraph: true,
|
||||
bisectInfo: git_commands.NewNullBisectInfo(),
|
||||
startIdx: 0,
|
||||
length: 5,
|
||||
showGraph: true,
|
||||
bisectInfo: git_commands.NewNullBisectInfo(),
|
||||
cherryPickedCommitShaSet: set.New[string](),
|
||||
expected: formatExpected(`
|
||||
sha1 pick commit1
|
||||
sha2 pick commit2
|
||||
@ -112,10 +116,11 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
|
||||
{Name: "commit4", Sha: "sha4", Parents: []string{"sha5"}},
|
||||
{Name: "commit5", Sha: "sha5", Parents: []string{"sha7"}},
|
||||
},
|
||||
startIdx: 1,
|
||||
length: 10,
|
||||
showGraph: true,
|
||||
bisectInfo: git_commands.NewNullBisectInfo(),
|
||||
startIdx: 1,
|
||||
length: 10,
|
||||
showGraph: true,
|
||||
bisectInfo: git_commands.NewNullBisectInfo(),
|
||||
cherryPickedCommitShaSet: set.New[string](),
|
||||
expected: formatExpected(`
|
||||
sha2 pick commit2
|
||||
sha3 ◯ commit3
|
||||
@ -132,10 +137,11 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
|
||||
{Name: "commit4", Sha: "sha4", Parents: []string{"sha5"}},
|
||||
{Name: "commit5", Sha: "sha5", Parents: []string{"sha7"}},
|
||||
},
|
||||
startIdx: 3,
|
||||
length: 2,
|
||||
showGraph: true,
|
||||
bisectInfo: git_commands.NewNullBisectInfo(),
|
||||
startIdx: 3,
|
||||
length: 2,
|
||||
showGraph: true,
|
||||
bisectInfo: git_commands.NewNullBisectInfo(),
|
||||
cherryPickedCommitShaSet: set.New[string](),
|
||||
expected: formatExpected(`
|
||||
sha4 ◯ commit4
|
||||
sha5 ◯ commit5
|
||||
@ -150,10 +156,11 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
|
||||
{Name: "commit4", Sha: "sha4", Parents: []string{"sha5"}},
|
||||
{Name: "commit5", Sha: "sha5", Parents: []string{"sha7"}},
|
||||
},
|
||||
startIdx: 0,
|
||||
length: 2,
|
||||
showGraph: true,
|
||||
bisectInfo: git_commands.NewNullBisectInfo(),
|
||||
startIdx: 0,
|
||||
length: 2,
|
||||
showGraph: true,
|
||||
bisectInfo: git_commands.NewNullBisectInfo(),
|
||||
cherryPickedCommitShaSet: set.New[string](),
|
||||
expected: formatExpected(`
|
||||
sha1 pick commit1
|
||||
sha2 pick commit2
|
||||
@ -168,10 +175,11 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
|
||||
{Name: "commit4", Sha: "sha4", Parents: []string{"sha5"}},
|
||||
{Name: "commit5", Sha: "sha5", Parents: []string{"sha7"}},
|
||||
},
|
||||
startIdx: 4,
|
||||
length: 2,
|
||||
showGraph: true,
|
||||
bisectInfo: git_commands.NewNullBisectInfo(),
|
||||
startIdx: 4,
|
||||
length: 2,
|
||||
showGraph: true,
|
||||
bisectInfo: git_commands.NewNullBisectInfo(),
|
||||
cherryPickedCommitShaSet: set.New[string](),
|
||||
expected: formatExpected(`
|
||||
sha5 ◯ commit5
|
||||
`),
|
||||
@ -185,10 +193,11 @@ func TestGetCommitListDisplayStrings(t *testing.T) {
|
||||
{Name: "commit4", Sha: "sha4", Parents: []string{"sha5"}, Action: "pick"},
|
||||
{Name: "commit5", Sha: "sha5", Parents: []string{"sha7"}},
|
||||
},
|
||||
startIdx: 0,
|
||||
length: 2,
|
||||
showGraph: true,
|
||||
bisectInfo: git_commands.NewNullBisectInfo(),
|
||||
startIdx: 0,
|
||||
length: 2,
|
||||
showGraph: true,
|
||||
bisectInfo: git_commands.NewNullBisectInfo(),
|
||||
cherryPickedCommitShaSet: set.New[string](),
|
||||
expected: formatExpected(`
|
||||
sha1 pick commit1
|
||||
sha2 pick commit2
|
||||
|
@ -17,15 +17,6 @@ func SplitLines(multilineString string) []string {
|
||||
return lines
|
||||
}
|
||||
|
||||
// TrimTrailingNewline - Trims the trailing newline
|
||||
// TODO: replace with `chomp` after refactor
|
||||
func TrimTrailingNewline(str string) string {
|
||||
if strings.HasSuffix(str, "\n") {
|
||||
return str[:len(str)-1]
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
// NormalizeLinefeeds - Removes all Windows and Mac style line feeds
|
||||
func NormalizeLinefeeds(str string) string {
|
||||
str = strings.Replace(str, "\r\n", "\n", -1)
|
||||
|
@ -36,29 +36,6 @@ func TestSplitLines(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestTrimTrailingNewline is a function.
|
||||
func TestTrimTrailingNewline(t *testing.T) {
|
||||
type scenario struct {
|
||||
str string
|
||||
expected string
|
||||
}
|
||||
|
||||
scenarios := []scenario{
|
||||
{
|
||||
"hello world !\n",
|
||||
"hello world !",
|
||||
},
|
||||
{
|
||||
"hello world !",
|
||||
"hello world !",
|
||||
},
|
||||
}
|
||||
|
||||
for _, s := range scenarios {
|
||||
assert.EqualValues(t, s.expected, TrimTrailingNewline(s.str))
|
||||
}
|
||||
}
|
||||
|
||||
// TestNormalizeLinefeeds is a function.
|
||||
func TestNormalizeLinefeeds(t *testing.T) {
|
||||
type scenario struct {
|
||||
|
18
vendor/github.com/jesseduffield/generics/maps/maps.go
generated
vendored
18
vendor/github.com/jesseduffield/generics/maps/maps.go
generated
vendored
@ -33,3 +33,21 @@ func TransformKeys[Key comparable, Value any, NewKey comparable](m map[Key]Value
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
func MapToSlice[Key comparable, Value any, Mapped any](m map[Key]Value, f func(Key, Value) Mapped) []Mapped {
|
||||
output := make([]Mapped, 0, len(m))
|
||||
for key, value := range m {
|
||||
output = append(output, f(key, value))
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
func Filter[Key comparable, Value any](m map[Key]Value, f func(Key, Value) bool) map[Key]Value {
|
||||
output := map[Key]Value{}
|
||||
for key, value := range m {
|
||||
if f(key, value) {
|
||||
output[key] = value
|
||||
}
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
10
vendor/github.com/jesseduffield/generics/set/set.go
generated
vendored
10
vendor/github.com/jesseduffield/generics/set/set.go
generated
vendored
@ -19,13 +19,9 @@ func NewFromSlice[T comparable](slice []T) *Set[T] {
|
||||
return &Set[T]{hashMap: hashMap}
|
||||
}
|
||||
|
||||
func (s *Set[T]) Add(value T) {
|
||||
s.hashMap[value] = true
|
||||
}
|
||||
|
||||
func (s *Set[T]) AddSlice(slice []T) {
|
||||
for _, value := range slice {
|
||||
s.Add(value)
|
||||
func (s *Set[T]) Add(values ...T) {
|
||||
for _, value := range values {
|
||||
s.hashMap[value] = true
|
||||
}
|
||||
}
|
||||
|
||||
|
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@ -120,7 +120,7 @@ github.com/integrii/flaggy
|
||||
# github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99
|
||||
## explicit
|
||||
github.com/jbenet/go-context/io
|
||||
# github.com/jesseduffield/generics v0.0.0-20220319042131-63614a800d5f
|
||||
# github.com/jesseduffield/generics v0.0.0-20220319062156-fa5cb8bde518
|
||||
## explicit; go 1.18
|
||||
github.com/jesseduffield/generics/maps
|
||||
github.com/jesseduffield/generics/set
|
||||
|
Loading…
x
Reference in New Issue
Block a user