1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-08-06 22:33:07 +02:00

Update linter (#4671)

- Update the golangci-lint configuration to use the latest version
(2.2.1)
- Enable a few more linter checks
- Improve the VS Code configuration so that we don't get spurious linter
warnings that wouldn't also show up on CI
- Provide a way to run the exact same golangci-lint version locally that
we use on CI. This is useful in case the globally installed version is a
newer one which emits more warnings.
This commit is contained in:
Stefan Haller
2025-07-01 11:08:24 +02:00
committed by GitHub
82 changed files with 470 additions and 388 deletions

View File

@ -169,9 +169,9 @@ jobs:
with:
go-version: 1.24.x
- name: Lint
uses: golangci/golangci-lint-action@v6.5.0
uses: golangci/golangci-lint-action@v8
with:
version: v1.64.6
version: v2.2.1
- name: errors
run: golangci-lint run
if: ${{ failure() }}

View File

@ -1,36 +1,114 @@
linters:
enable:
- gofumpt
- thelper
- goimports
- tparallel
- wastedassign
- unparam
- prealloc
- unconvert
- exhaustive
- makezero
- nakedret
- copyloopvar
fast: false
linters-settings:
copyloopvar:
# Check all assigning the loop variable to another variable.
# Default: false
# If true, an assignment like `a := x` will be detected as an error.
check-alias: true
exhaustive:
default-signifies-exhaustive: true
staticcheck:
# SA1019 is for checking that we're not using fields marked as deprecated
# in a comment. It decides this in a loose way so I'm silencing it. Also because
# it's tripping on our own structs.
checks: ["all", "-SA1019"]
nakedret:
# the gods will judge me but I just don't like naked returns at all
max-func-lines: 0
version: "2"
run:
go: "1.24"
timeout: 10m
linters:
enable:
- copyloopvar
- errorlint
- exhaustive
- intrange
- makezero
- nakedret
- nolintlint
- prealloc
- revive
- thelper
- tparallel
- unconvert
- unparam
- wastedassign
settings:
copyloopvar:
check-alias: true
exhaustive:
default-signifies-exhaustive: true
nakedret:
# the gods will judge me but I just don't like naked returns at all
max-func-lines: 0
staticcheck:
checks:
- all
# SA1019 is for checking that we're not using fields marked as
# deprecated in a comment. It decides this in a loose way so I'm
# silencing it. Also because it's tripping on our own structs.
- -SA1019
# ST1003 complains about names like remoteUrl or itemId (should be
# remoteURL and itemID). While I like these suggestions, it also
# complains about enum constants that are all caps, and we use these and
# I like them, and also about camelCase identifiers that contain an
# underscore, which we also use in a few places. Since it can't be
# configured to ignore specific cases, and I don't want to use nolint
# comments in the code, we have to disable it altogether.
- -ST1003 # Poorly chosen identifier
# Probably a good idea, but we first have to review our error reporting
# strategy to be able to use it everywhere.
- -ST1005 # Error strings should not be capitalized
# Many of our classes use self as a receiver name, and we think that's fine.
- -ST1006 # Use of self or this as receiver name
# De Morgan's law suggests to replace `!(a && b)` with `!a || !b`; but
# sometimes I find one more readable than the other, so I want to decide
# that myself.
- -QF1001 # De Morgan's law
# QF1003 is about using a tagged switch instead of an if-else chain. In
# many cases this is a useful suggestion; however, sometimes the change
# is only possible by adding a default case to the switch (when there
# was no `else` block in the original code), in which case I don't find
# it to be an improvement.
- -QF1003 # Could replace with tagged switch
# We need to review our use of embedded fields. I suspect that in some
# cases the fix is not to remove the selector for the embedded field,
# but to turn the embedded field into a named field.
- -QF1008 # Could remove embedded field from selector
# The following checks are all disabled by default in golangci-lint, but
# we disable them again explicitly here to make it easier to keep this
# list in sync with the gopls config in .vscode/settings.json.
- -ST1000, # At least one file in a package should have a package comment
- -ST1020, # The documentation of an exported function should start with the function's name
- -ST1021, # The documentation of an exported type should start with type's name
- -ST1022, # The documentation of an exported variable or constant should start with variable's name
dot-import-whitelist:
- github.com/jesseduffield/lazygit/pkg/integration/components
revive:
severity: warning
rules:
- name: atomic
- name: context-as-argument
- name: context-keys-type
- name: error-naming
- name: var-declaration
- name: package-comments
- name: range
- name: time-naming
- name: indent-error-flow
- name: errorf
- name: superfluous-else
exclusions:
generated: lax
presets:
- comments
- common-false-positives
- legacy
- std-error-handling
paths:
- third_party$
- builtin$
- examples$
formatters:
enable:
- gofumpt
- goimports
exclusions:
generated: lax
paths:
- third_party$
- builtin$
- examples$

24
.vscode/settings.json vendored
View File

@ -1,5 +1,29 @@
{
"gopls": {
"formatting.gofumpt": true,
"ui.diagnostic.staticcheck": true,
"ui.diagnostic.analyses": {
// This list must match the one in .golangci.yml
"SA1019": false,
"ST1003": false,
"ST1005": false,
"ST1006": false,
"QF1001": false,
"QF1003": false,
"QF1008": false,
"ST1000": false,
"ST1020": false,
"ST1021": false,
"ST1022": false,
// Dot imports; this warning is enabled in .golangci.yml, but with an
// extra dot-import-whitelist config. Because I couldn't figure out how to
// specify that extra config for gopls, I'm disabling the check altogether
// here.
"ST1001": false,
},
},
"go.alternateTools": {
"golangci-lint-v2": "${workspaceFolder}/.bin/golangci-lint",
},
"go.lintTool": "golangci-lint-v2",
}

View File

@ -40,7 +40,7 @@ format:
.PHONY: lint
lint:
golangci-lint run
./scripts/lint.sh
# For more details about integration test, see https://github.com/jesseduffield/lazygit/blob/master/pkg/integration/README.md.
.PHONY: integration-test-tui

View File

@ -86,9 +86,9 @@ func newLogger(cfg config.AppConfigurer) *logrus.Entry {
log.Fatal(err)
}
return logs.NewDevelopmentLogger(logPath)
} else {
return logs.NewProductionLogger()
}
return logs.NewProductionLogger()
}
// NewApp bootstrap a new application

View File

@ -21,9 +21,8 @@ type TodoLine struct {
func (self *TodoLine) ToString() string {
if self.Action == "break" {
return self.Action + "\n"
} else {
return self.Action + " " + self.Commit.Hash() + " " + self.Commit.Name + "\n"
}
return self.Action + " " + self.Commit.Hash() + " " + self.Commit.Name + "\n"
}
func TodoLinesToString(todoLines []TodoLine) string {

View File

@ -28,7 +28,7 @@ func (self *gitCmdObjRunner) Run(cmdObj *oscommands.CmdObj) error {
func (self *gitCmdObjRunner) RunWithOutput(cmdObj *oscommands.CmdObj) (string, error) {
var output string
var err error
for i := 0; i < RetryCount; i++ {
for range RetryCount {
newCmdObj := cmdObj.Clone()
output, err = self.innerRunner.RunWithOutput(newCmdObj)
@ -47,7 +47,7 @@ func (self *gitCmdObjRunner) RunWithOutput(cmdObj *oscommands.CmdObj) (string, e
func (self *gitCmdObjRunner) RunWithOutputs(cmdObj *oscommands.CmdObj) (string, string, error) {
var stdout, stderr string
var err error
for i := 0; i < RetryCount; i++ {
for range RetryCount {
newCmdObj := cmdObj.Clone()
stdout, stderr, err = self.innerRunner.RunWithOutputs(newCmdObj)

View File

@ -356,9 +356,8 @@ func parseDifference(track string, regexStr string) string {
match := re.FindStringSubmatch(track)
if len(match) > 1 {
return match[1]
} else {
return "0"
}
return "0"
}
// TODO: only look at the new reflog commits, and otherwise store the recencies in

View File

@ -149,9 +149,8 @@ func (self *CommitCommands) CommitEditorCmdObj() *oscommands.CmdObj {
func (self *CommitCommands) signoffFlag() string {
if self.UserConfig().Git.Commit.SignOff {
return "--signoff"
} else {
return ""
}
return ""
}
func (self *CommitCommands) GetCommitMessage(commitHash string) (string, error) {

View File

@ -16,16 +16,16 @@ import (
"github.com/stretchr/testify/assert"
)
var commitsOutput = strings.Replace(`0eea75e8c631fba6b58135697835d58ba4c18dbc|1640826609|Jesse Duffield|jessedduffield@gmail.com|HEAD -> better-tests|b21997d6b4cbdf84b149|>|better typing for rebase mode
var commitsOutput = strings.ReplaceAll(`0eea75e8c631fba6b58135697835d58ba4c18dbc|1640826609|Jesse Duffield|jessedduffield@gmail.com|HEAD -> better-tests|b21997d6b4cbdf84b149|>|better typing for rebase mode
b21997d6b4cbdf84b149d8e6a2c4d06a8e9ec164|1640824515|Jesse Duffield|jessedduffield@gmail.com|origin/better-tests|e94e8fc5b6fab4cb755f|>|fix logging
e94e8fc5b6fab4cb755f29f1bdb3ee5e001df35c|1640823749|Jesse Duffield|jessedduffield@gmail.com|tag: 123, tag: 456|d8084cd558925eb7c9c3|>|refactor
d8084cd558925eb7c9c38afeed5725c21653ab90|1640821426|Jesse Duffield|jessedduffield@gmail.com||65f910ebd85283b5cce9|>|WIP
65f910ebd85283b5cce9bf67d03d3f1a9ea3813a|1640821275|Jesse Duffield|jessedduffield@gmail.com||26c07b1ab33860a1a759|>|WIP
26c07b1ab33860a1a7591a0638f9925ccf497ffa|1640750752|Jesse Duffield|jessedduffield@gmail.com||3d4470a6c072208722e5|>|WIP
3d4470a6c072208722e5ae9a54bcb9634959a1c5|1640748818|Jesse Duffield|jessedduffield@gmail.com||053a66a7be3da43aacdc|>|WIP
053a66a7be3da43aacdc7aa78e1fe757b82c4dd2|1640739815|Jesse Duffield|jessedduffield@gmail.com||985fe482e806b172aea4|>|refactoring the config struct`, "|", "\x00", -1)
053a66a7be3da43aacdc7aa78e1fe757b82c4dd2|1640739815|Jesse Duffield|jessedduffield@gmail.com||985fe482e806b172aea4|>|refactoring the config struct`, "|", "\x00")
var singleCommitOutput = strings.Replace(`0eea75e8c631fba6b58135697835d58ba4c18dbc|1640826609|Jesse Duffield|jessedduffield@gmail.com|HEAD -> better-tests|b21997d6b4cbdf84b149|>|better typing for rebase mode`, "|", "\x00", -1)
var singleCommitOutput = strings.ReplaceAll(`0eea75e8c631fba6b58135697835d58ba4c18dbc|1640826609|Jesse Duffield|jessedduffield@gmail.com|HEAD -> better-tests|b21997d6b4cbdf84b149|>|better typing for rebase mode`, "|", "\x00")
func TestGetCommits(t *testing.T) {
type scenario struct {

View File

@ -97,7 +97,7 @@ func buildGitCommon(deps commonDeps) *GitCommon {
func buildRepo() *gogit.Repository {
// TODO: think of a way to actually mock this out
var repo *gogit.Repository = nil
var repo *gogit.Repository
return repo
}

View File

@ -110,8 +110,8 @@ type FileDiff struct {
LinesDeleted int
}
func (fileLoader *FileLoader) getFileDiffs() (map[string]FileDiff, error) {
diffs, err := fileLoader.gitDiffNumStat()
func (self *FileLoader) getFileDiffs() (map[string]FileDiff, error) {
diffs, err := self.gitDiffNumStat()
if err != nil {
return nil, err
}
@ -157,8 +157,8 @@ type FileStatus struct {
PreviousPath string
}
func (fileLoader *FileLoader) gitDiffNumStat() (string, error) {
return fileLoader.cmd.New(
func (self *FileLoader) gitDiffNumStat() (string, error) {
return self.cmd.New(
NewGitCmd("diff").
Arg("--numstat").
Arg("-z").

View File

@ -32,9 +32,8 @@ func (self *GitCommandBuilder) ArgIf(condition bool, ifTrue ...string) *GitComma
func (self *GitCommandBuilder) ArgIfElse(condition bool, ifTrue string, ifFalse string) *GitCommandBuilder {
if condition {
return self.Arg(ifTrue)
} else {
return self.Arg(ifFalse)
}
return self.Arg(ifFalse)
}
func (self *GitCommandBuilder) Config(value string) *GitCommandBuilder {

View File

@ -327,9 +327,8 @@ func (self *RebaseCommands) MoveFixupCommitDown(commits []*models.Commit, target
func todoFromCommit(commit *models.Commit) utils.Todo {
if commit.Action == todo.UpdateRef {
return utils.Todo{Ref: commit.Name}
} else {
return utils.Todo{Hash: commit.Hash()}
}
return utils.Todo{Hash: commit.Hash()}
}
// Sets the action for the given commits in the git-rebase-todo file
@ -412,9 +411,9 @@ func (self *RebaseCommands) BeginInteractiveRebaseForCommit(
instruction: daemon.NewInsertBreakInstruction(),
keepCommitsThatBecomeEmpty: keepCommitsThatBecomeEmpty,
}).Run()
} else {
return self.BeginInteractiveRebaseForCommitRange(commits, commitIndex, commitIndex, keepCommitsThatBecomeEmpty)
}
return self.BeginInteractiveRebaseForCommitRange(commits, commitIndex, commitIndex, keepCommitsThatBecomeEmpty)
}
func (self *RebaseCommands) BeginInteractiveRebaseForCommitRange(
@ -574,7 +573,7 @@ func getBaseHashOrRoot(commits []*models.Commit, index int) string {
// at time of writing)
if index < len(commits) {
return commits[index].Hash()
} else {
return "--root"
}
return "--root"
}

View File

@ -14,12 +14,12 @@ import (
"github.com/stretchr/testify/assert"
)
var reflogOutput = strings.Replace(`c3c4b66b64c97ffeecde|1643150483|checkout: moving from A to B|51baa8c1
var reflogOutput = strings.ReplaceAll(`c3c4b66b64c97ffeecde|1643150483|checkout: moving from A to B|51baa8c1
c3c4b66b64c97ffeecde|1643150483|checkout: moving from B to A|51baa8c1
c3c4b66b64c97ffeecde|1643150483|checkout: moving from A to B|51baa8c1
c3c4b66b64c97ffeecde|1643150483|checkout: moving from master to A|51baa8c1
f4ddf2f0d4be4ccc7efa|1643149435|checkout: moving from A to master|51baa8c1
`, "|", "\x00", -1)
`, "|", "\x00")
func TestGetReflogCommits(t *testing.T) {
type scenario struct {

View File

@ -21,7 +21,7 @@ type RepoPaths struct {
isBareRepo bool
}
var gitPathFormatVersion GitVersion = GitVersion{2, 31, 0, ""}
var gitPathFormatVersion = GitVersion{2, 31, 0, ""}
// Path to the current worktree. If we're in the main worktree, this will
// be the same as RepoPath()

View File

@ -184,9 +184,7 @@ func TestGetRepoPaths(t *testing.T) {
Expected: nil,
Err: func(getRevParseArgs argFn) error {
args := strings.Join(getRevParseArgs(), " ")
return errors.New(
fmt.Sprintf("'git %v --show-toplevel --absolute-git-dir --git-common-dir --is-bare-repository --show-superproject-working-tree' failed: fatal: invalid gitfile format: /path/to/repo/worktree2/.git", args),
)
return fmt.Errorf("'git %v --show-toplevel --absolute-git-dir --git-common-dir --is-bare-repository --show-superproject-working-tree' failed: fatal: invalid gitfile format: /path/to/repo/worktree2/.git", args)
},
},
}

View File

@ -53,7 +53,7 @@ outer:
if err != nil {
return self.getUnfilteredStashEntries()
}
currentStashEntry = self.stashEntryFromLine(lines[i], idx)
currentStashEntry = stashEntryFromLine(lines[i], idx)
for i+1 < len(lines) && !isAStash(lines[i+1]) {
i++
if lines[i] == filterPath {
@ -70,11 +70,11 @@ func (self *StashLoader) getUnfilteredStashEntries() []*models.StashEntry {
rawString, _ := self.cmd.New(cmdArgs).DontLog().RunWithOutput()
return lo.Map(utils.SplitNul(rawString), func(line string, index int) *models.StashEntry {
return self.stashEntryFromLine(line, index)
return stashEntryFromLine(line, index)
})
}
func (c *StashLoader) stashEntryFromLine(line string, index int) *models.StashEntry {
func stashEntryFromLine(line string, index int) *models.StashEntry {
model := &models.StashEntry{
Name: line,
Index: index,

View File

@ -49,9 +49,8 @@ func (self *SubmoduleCommands) GetConfigs(parentModule *models.SubmoduleConfig)
if len(matches) > 0 {
return matches[1], true
} else {
return "", false
}
return "", false
}
configs := []*models.SubmoduleConfig{}

View File

@ -66,9 +66,8 @@ func (self *WorkingTreeCommands) UnstageAll() error {
func (self *WorkingTreeCommands) UnStageFile(paths []string, tracked bool) error {
if tracked {
return self.UnstageTrackedFiles(paths)
} else {
return self.UnstageUntrackedFiles(paths)
}
return self.UnstageUntrackedFiles(paths)
}
func (self *WorkingTreeCommands) UnstageTrackedFiles(paths []string) error {

View File

@ -2,6 +2,7 @@ package git_config
import (
"bytes"
"errors"
"fmt"
"io"
"os/exec"
@ -39,7 +40,8 @@ func runGitConfigCmd(cmd *exec.Cmd) (string, error) {
cmd.Stderr = io.Discard
err := cmd.Run()
if exitError, ok := err.(*exec.ExitError); ok {
var exitError *exec.ExitError
if errors.As(err, &exitError) {
if waitStatus, ok := exitError.Sys().(syscall.WaitStatus); ok {
if waitStatus.ExitStatus() == 1 {
return "", fmt.Errorf("the key is not found for %s", cmd.Args)

View File

@ -46,9 +46,8 @@ func (self *HostingServiceMgr) GetPullRequestURL(from string, to string) (string
if to == "" {
return gitService.getPullRequestURLIntoDefaultBranch(url.QueryEscape(from)), nil
} else {
return gitService.getPullRequestURLIntoTargetBranch(url.QueryEscape(from), url.QueryEscape(to)), nil
}
return gitService.getPullRequestURLIntoTargetBranch(url.QueryEscape(from), url.QueryEscape(to)), nil
}
func (self *HostingServiceMgr) GetCommitURL(commitHash string) (string, error) {

View File

@ -222,7 +222,7 @@ func (c *OSCommand) PipeCommands(cmdObjs ...*CmdObj) error {
c.LogCommand(logCmdStr, true)
for i := 0; i < len(cmds)-1; i++ {
for i := range len(cmds) - 1 {
stdout, err := cmds[i].StdoutPipe()
if err != nil {
return err
@ -283,7 +283,7 @@ func PrepareForChildren(cmd *exec.Cmd) {
}
func (c *OSCommand) CopyToClipboard(str string) error {
escaped := strings.Replace(str, "\n", "\\n", -1)
escaped := strings.ReplaceAll(str, "\n", "\\n")
truncated := utils.TruncateWithEllipsis(escaped, 40)
msg := utils.ResolvePlaceholderString(

View File

@ -56,7 +56,7 @@ func (self *Patch) HunkStartIdx(hunkIndex int) int {
hunkIndex = lo.Clamp(hunkIndex, 0, len(self.hunks)-1)
result := len(self.header)
for i := 0; i < hunkIndex; i++ {
for i := range hunkIndex {
result += self.hunks[i].lineCount()
}
return result

View File

@ -91,7 +91,7 @@ func (p *PatchBuilder) addFileWhole(info *fileInfo) {
// 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++ {
for i := range lineCount {
info.includedLineIndices[i] = i
}
}
@ -211,9 +211,8 @@ func (p *PatchBuilder) RenderPatchForFile(opts RenderPatchForFileOpts) string {
if opts.Plain {
return patch.FormatPlain()
} else {
return patch.FormatView(FormatViewOpts{})
}
return patch.FormatView(FormatViewOpts{})
}
func (p *PatchBuilder) renderEachFilePatch(plain bool) []string {

View File

@ -84,9 +84,9 @@ func (self *patchTransformer) transformHeader() []string {
result = append(result, line)
}
return result
} else {
return self.patch.header
}
return self.patch.header
}
func (self *patchTransformer) transformHunks() []*Hunk {

View File

@ -288,7 +288,7 @@ func computeMigratedConfig(path string, content []byte, changes *ChangesSet) ([]
for _, pathToReplace := range pathsToReplace {
err, didReplace := yaml_utils.RenameYamlKey(&rootNode, pathToReplace.oldPath, pathToReplace.newName)
if err != nil {
return nil, false, fmt.Errorf("Couldn't migrate config file at `%s` for key %s: %s", path, strings.Join(pathToReplace.oldPath, "."), err)
return nil, false, fmt.Errorf("Couldn't migrate config file at `%s` for key %s: %w", path, strings.Join(pathToReplace.oldPath, "."), err)
}
if didReplace {
changes.Add(fmt.Sprintf("Renamed '%s' to '%s'", strings.Join(pathToReplace.oldPath, "."), pathToReplace.newName))
@ -297,27 +297,27 @@ func computeMigratedConfig(path string, content []byte, changes *ChangesSet) ([]
err = changeNullKeybindingsToDisabled(&rootNode, changes)
if err != nil {
return nil, false, fmt.Errorf("Couldn't migrate config file at `%s`: %s", path, err)
return nil, false, fmt.Errorf("Couldn't migrate config file at `%s`: %w", path, err)
}
err = changeElementToSequence(&rootNode, []string{"git", "commitPrefix"}, changes)
if err != nil {
return nil, false, fmt.Errorf("Couldn't migrate config file at `%s`: %s", path, err)
return nil, false, fmt.Errorf("Couldn't migrate config file at `%s`: %w", path, err)
}
err = changeCommitPrefixesMap(&rootNode, changes)
if err != nil {
return nil, false, fmt.Errorf("Couldn't migrate config file at `%s`: %s", path, err)
return nil, false, fmt.Errorf("Couldn't migrate config file at `%s`: %w", path, err)
}
err = changeCustomCommandStreamAndOutputToOutputEnum(&rootNode, changes)
if err != nil {
return nil, false, fmt.Errorf("Couldn't migrate config file at `%s`: %s", path, err)
return nil, false, fmt.Errorf("Couldn't migrate config file at `%s`: %w", path, err)
}
err = migrateAllBranchesLogCmd(&rootNode, changes)
if err != nil {
return nil, false, fmt.Errorf("Couldn't migrate config file at `%s`: %s", path, err)
return nil, false, fmt.Errorf("Couldn't migrate config file at `%s`: %w", path, err)
}
// Add more migrations here...

View File

@ -56,7 +56,7 @@ func validateKeybindingsRecurse(path string, node any) error {
}
}
} else if value.Kind() == reflect.Slice {
for i := 0; i < value.Len(); i++ {
for i := range value.Len() {
if err := validateKeybindingsRecurse(
fmt.Sprintf("%s[%d]", path, i), value.Index(i).Interface()); err != nil {
return err

View File

@ -48,7 +48,7 @@ func (gui *Gui) LogCommand(cmdStr string, commandLine bool) {
textStyle = style.FgMagenta
}
gui.GuiLog = append(gui.GuiLog, cmdStr)
indentedCmdStr := " " + strings.Replace(cmdStr, "\n", "\n ", -1)
indentedCmdStr := " " + strings.ReplaceAll(cmdStr, "\n", "\n ")
fmt.Fprint(gui.Views.Extras, "\n"+textStyle.Sprint(indentedCmdStr))
}

View File

@ -257,11 +257,11 @@ func TestListRenderer_ModelIndexToViewIndex_and_back(t *testing.T) {
// Need to render first so that it knows the non-model items
self.renderLines(-1, -1)
for i := 0; i < len(s.modelIndices); i++ {
for i := range len(s.modelIndices) {
assert.Equal(t, s.expectedViewIndices[i], self.ModelIndexToViewIndex(s.modelIndices[i]))
}
for i := 0; i < len(s.viewIndices); i++ {
for i := range len(s.viewIndices) {
assert.Equal(t, s.expectedModelIndices[i], self.ViewIndexToModelIndex(s.viewIndices[i]))
}
})

View File

@ -144,7 +144,7 @@ func (self *MenuViewModel) GetNonModelItems() []*NonModelItem {
}
menuItems := self.FilteredListViewModel.GetItems()
var prevSection *types.MenuSection = nil
var prevSection *types.MenuSection
for i, menuItem := range menuItems {
if menuItem.Section != nil && menuItem.Section != prevSection {
if prevSection != nil {

View File

@ -79,9 +79,8 @@ func (self *SuggestionsContext) RefreshSuggestions() {
if findSuggestionsFn != nil {
suggestions := findSuggestionsFn(self.c.GetPromptInput())
return func() { self.SetSuggestions(suggestions) }
} else {
return func() {}
}
return func() {}
})
}

View File

@ -77,9 +77,8 @@ func (self *ListCursor) SetSelectionRangeAndMode(selectedIdx, rangeStartIdx int,
func (self *ListCursor) GetSelectionRangeAndMode() (int, int, RangeSelectMode) {
if self.IsSelectingRange() {
return self.selectedIdx, self.rangeStartIdx, self.rangeSelectMode
} else {
return self.selectedIdx, self.selectedIdx, self.rangeSelectMode
}
return self.selectedIdx, self.selectedIdx, self.rangeSelectMode
}
func (self *ListCursor) clampValue(value int) int {

View File

@ -24,7 +24,7 @@ func OnFocusWrapper(f func() error) func(opts types.OnFocusOpts) error {
func (gui *Gui) defaultSideContext() types.Context {
if gui.State.Modes.Filtering.Active() {
return gui.State.Contexts.LocalCommits
} else {
return gui.State.Contexts.Files
}
return gui.State.Contexts.Files
}

View File

@ -54,9 +54,8 @@ func (self *BisectController) openMenu(commit *models.Commit) error {
info := self.c.Git().Bisect.GetInfo()
if info.Started() {
return self.openMidBisectMenu(info, commit)
} else {
return self.openStartBisectMenu(info, commit)
}
return self.openStartBisectMenu(info, commit)
}
func (self *BisectController) openMidBisectMenu(info *git_commands.BisectInfo, commit *models.Commit) error {
@ -280,11 +279,11 @@ func (self *BisectController) afterBisectMarkRefresh(selectCurrent bool, waitToR
if waitToReselect {
return self.c.Refresh(types.RefreshOptions{Mode: types.SYNC, Scope: []types.RefreshableView{}, Then: selectFn})
} else {
_ = selectFn()
return self.c.Helpers().Bisect.PostBisectCommandRefresh()
}
_ = selectFn()
return self.c.Helpers().Bisect.PostBisectCommandRefresh()
}
func (self *BisectController) selectCurrentBisectCommit() {

View File

@ -657,15 +657,15 @@ func (self *BranchesController) fastForward(branch *models.Branch) error {
)
_ = self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC})
return err
} else {
self.c.LogAction(action)
err := self.c.Git().Sync.FastForward(
task, branch.Name, branch.UpstreamRemote, branch.UpstreamBranch,
)
_ = self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.BRANCHES}})
return err
}
self.c.LogAction(action)
err := self.c.Git().Sync.FastForward(
task, branch.Name, branch.UpstreamRemote, branch.UpstreamBranch,
)
_ = self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC, Scope: []types.RefreshableView{types.BRANCHES}})
return err
})
}

View File

@ -153,7 +153,7 @@ func (self *CommitMessageController) handleCommitIndexChange(value int) error {
func (self *CommitMessageController) setCommitMessageAtIndex(index int) (bool, error) {
commitMessage, err := self.c.Git().Commit.GetCommitMessageFromHistory(index)
if err != nil {
if err == git_commands.ErrInvalidCommitIndex {
if errors.Is(err, git_commands.ErrInvalidCommitIndex) {
return false, nil
}
return false, errors.New(self.c.Tr.CommitWithoutMessageErr)

View File

@ -189,9 +189,9 @@ func (self *CustomPatchOptionsMenuAction) handleMovePatchIntoWorkingTree() error
})
return nil
} else {
return pull(false)
}
return pull(false)
}
func (self *CustomPatchOptionsMenuAction) handlePullPatchIntoNewCommit() error {

View File

@ -18,7 +18,7 @@ import (
)
type FilesController struct {
baseController // nolint: unused
baseController
*ListControllerTrait[*filetree.FileNode]
c *ControllerCommon
}
@ -901,11 +901,10 @@ func (self *FilesController) setStatusFiltering(filter filetree.FileTreeDisplayF
// because the untracked files filter applies when running `git status`.
if previousFilter != filter && (previousFilter == filetree.DisplayUntracked || filter == filetree.DisplayUntracked) {
return self.c.Refresh(types.RefreshOptions{Scope: []types.RefreshableView{types.FILES}, Mode: types.ASYNC})
} else {
self.c.PostRefreshUpdate(self.context())
return nil
}
self.c.PostRefreshUpdate(self.context())
return nil
}
func (self *FilesController) edit(nodes []*filetree.FileNode) error {

View File

@ -37,9 +37,9 @@ func (self *GpgHelper) WithGpgHandling(cmdObj *oscommands.CmdObj, configKey git_
}
return err
} else {
return self.runAndStream(cmdObj, waitingStatus, onSuccess, refreshScope)
}
return self.runAndStream(cmdObj, waitingStatus, onSuccess, refreshScope)
}
func (self *GpgHelper) runAndStream(cmdObj *oscommands.CmdObj, waitingStatus string, onSuccess func() error, refreshScope []types.RefreshableView) error {

View File

@ -162,9 +162,8 @@ func (self *MergeAndRebaseHelper) CheckMergeOrRebaseWithRefreshOptions(result er
} else if strings.Contains(result.Error(), "No rebase in progress?") {
// assume in this case that we're already done
return nil
} else {
return self.CheckForConflicts(result)
}
return self.CheckForConflicts(result)
}
func (self *MergeAndRebaseHelper) CheckMergeOrRebase(result error) error {

View File

@ -56,9 +56,9 @@ func (self *RefsHelper) CheckoutRef(ref string, options types.CheckoutRefOptions
withCheckoutStatus := func(f func(gocui.Task) error) error {
if found {
return self.c.WithInlineStatus(localBranch, types.ItemOperationCheckingOut, context.LOCAL_BRANCHES_CONTEXT_KEY, f)
} else {
return self.c.WithWaitingStatus(waitingStatus, f)
}
return self.c.WithWaitingStatus(waitingStatus, f)
}
return withCheckoutStatus(func(gocui.Task) error {
@ -563,7 +563,7 @@ func (self *RefsHelper) CanMoveCommitsToNewBranch() *types.DisabledReason {
// SanitizedBranchName will remove all spaces in favor of a dash "-" to meet
// git's branch naming requirement.
func SanitizedBranchName(input string) string {
return strings.Replace(input, " ", "-", -1)
return strings.ReplaceAll(input, " ", "-")
}
// Checks if the given branch name is a remote branch, and returns the name of

View File

@ -385,9 +385,8 @@ func splitMainPanelSideBySide(args WindowArrangementArgs) bool {
default:
if args.Width < 200 && args.Height > 30 { // 2 80 character width panels + 40 width for side panel
return false
} else {
return true
}
return true
}
}
@ -431,11 +430,11 @@ func sidePanelChildren(args WindowArrangementArgs) func(width int, height int) [
Window: window,
Weight: 1,
}
} else {
return &boxlayout.Box{
Window: window,
Size: 0,
}
}
return &boxlayout.Box{
Window: window,
Size: 0,
}
}
@ -469,33 +468,33 @@ func sidePanelChildren(args WindowArrangementArgs) func(width int, height int) [
accordionBox(&boxlayout.Box{Window: "commits", Weight: 1}),
accordionBox(getDefaultStashWindowBox(args)),
}
} else {
squashedHeight := 1
if height >= 21 {
squashedHeight = 3
}
}
squashedSidePanelBox := func(window string) *boxlayout.Box {
if window == args.CurrentSideWindow {
return &boxlayout.Box{
Window: window,
Weight: 1,
}
} else {
return &boxlayout.Box{
Window: window,
Size: squashedHeight,
}
squashedHeight := 1
if height >= 21 {
squashedHeight = 3
}
squashedSidePanelBox := func(window string) *boxlayout.Box {
if window == args.CurrentSideWindow {
return &boxlayout.Box{
Window: window,
Weight: 1,
}
}
return []*boxlayout.Box{
squashedSidePanelBox("status"),
squashedSidePanelBox("files"),
squashedSidePanelBox("branches"),
squashedSidePanelBox("commits"),
squashedSidePanelBox("stash"),
return &boxlayout.Box{
Window: window,
Size: squashedHeight,
}
}
return []*boxlayout.Box{
squashedSidePanelBox("status"),
squashedSidePanelBox("files"),
squashedSidePanelBox("branches"),
squashedSidePanelBox("commits"),
squashedSidePanelBox("stash"),
}
}
}

View File

@ -245,7 +245,7 @@ func (self *WorkingTreeHelper) commitPrefixConfigsForRepo() []config.CommitPrefi
cfg, ok := self.c.UserConfig().Git.CommitPrefixes[self.c.Git().RepoPaths.RepoName()]
if ok {
return append(cfg, self.c.UserConfig().Git.CommitPrefix...)
} else {
return self.c.UserConfig().Git.CommitPrefix
}
return self.c.UserConfig().Git.CommitPrefix
}

View File

@ -132,24 +132,24 @@ func (self *WorktreeHelper) NewWorktreeCheckout(base string, canCheckoutBase boo
},
})
return nil
} else {
// prompt for the new branch name where a blank means we just check out the branch
self.c.Prompt(types.PromptOpts{
Title: self.c.Tr.NewBranchName,
HandleConfirm: func(branchName string) error {
if branchName == "" {
return errors.New(self.c.Tr.BranchNameCannotBeBlank)
}
opts.Branch = branchName
return f()
},
})
return nil
}
// prompt for the new branch name where a blank means we just check out the branch
self.c.Prompt(types.PromptOpts{
Title: self.c.Tr.NewBranchName,
HandleConfirm: func(branchName string) error {
if branchName == "" {
return errors.New(self.c.Tr.BranchNameCannotBeBlank)
}
opts.Branch = branchName
return f()
},
})
return nil
},
})

View File

@ -109,10 +109,11 @@ func (self *ListController) handleLineChangeAux(f func(int), change int) error {
// we're not constantly re-rendering the main view.
cursorMoved := before != after
if cursorMoved {
if change == -1 {
switch change {
case -1:
checkScrollUp(self.context.GetViewTrait(), self.c.UserConfig(),
self.context.ModelIndexToViewIndex(before), self.context.ModelIndexToViewIndex(after))
} else if change == 1 {
case 1:
checkScrollDown(self.context.GetViewTrait(), self.c.UserConfig(),
self.context.ModelIndexToViewIndex(before), self.context.ModelIndexToViewIndex(after))
}

View File

@ -87,7 +87,7 @@ func (self *ListControllerTrait[T]) itemRangeSelected(callbacks ...func([]T, int
}
}
func (self *ListControllerTrait[T]) itemsSelected(callbacks ...func([]T) *types.DisabledReason) func() *types.DisabledReason { //nolint:unused
func (self *ListControllerTrait[T]) itemsSelected(callbacks ...func([]T) *types.DisabledReason) func() *types.DisabledReason {
return func() *types.DisabledReason {
items, _, _ := self.getSelectedItems()
if len(items) == 0 {

View File

@ -92,27 +92,27 @@ func (self *SyncController) push(currentBranch *models.Branch) error {
opts := pushOpts{remoteBranchStoredLocally: currentBranch.RemoteBranchStoredLocally()}
if currentBranch.IsBehindForPush() {
return self.requestToForcePush(currentBranch, opts)
} else {
return self.pushAux(currentBranch, opts)
}
} else {
if self.c.Git().Config.GetPushToCurrent() {
return self.pushAux(currentBranch, pushOpts{setUpstream: true})
} else {
return self.c.Helpers().Upstream.PromptForUpstreamWithInitialContent(currentBranch, func(upstream string) error {
upstreamRemote, upstreamBranch, err := self.c.Helpers().Upstream.ParseUpstream(upstream)
if err != nil {
return err
}
return self.pushAux(currentBranch, pushOpts{
setUpstream: true,
upstreamRemote: upstreamRemote,
upstreamBranch: upstreamBranch,
})
})
}
return self.pushAux(currentBranch, opts)
}
if self.c.Git().Config.GetPushToCurrent() {
return self.pushAux(currentBranch, pushOpts{setUpstream: true})
}
return self.c.Helpers().Upstream.PromptForUpstreamWithInitialContent(currentBranch, func(upstream string) error {
upstreamRemote, upstreamBranch, err := self.c.Helpers().Upstream.ParseUpstream(upstream)
if err != nil {
return err
}
return self.pushAux(currentBranch, pushOpts{
setUpstream: true,
upstreamRemote: upstreamRemote,
upstreamBranch: upstreamBranch,
})
})
}
func (self *SyncController) pull(currentBranch *models.Branch) error {

View File

@ -180,7 +180,7 @@ func (self *FilesController) Explode(v *gocui.View, onDone func()) {
self.c.OnWorker(func(_ gocui.Task) error {
max := 25
for i := 0; i < max; i++ {
for i := range max {
image := getExplodeImage(width, height, i, max)
style := styles[(i*len(styles)/max)%len(styles)]
coloredImage := style.Sprint(image)
@ -229,8 +229,8 @@ func getExplodeImage(width int, height int, frame int, max int) string {
innerRadius = (progress - 0.5) * 2 * maxRadius
}
for y := 0; y < height; y++ {
for x := 0; x < width; x++ {
for y := range height {
for x := range width {
// calculate distance from center, scale x by 2 to compensate for character aspect ratio
distance := math.Hypot(float64(x-centerX), float64(y-centerY)*2)

View File

@ -138,9 +138,8 @@ func (self *FileTreeViewModel) findNewSelectedIdx(prevNodes []*FileNode, currNod
}
if node.File != nil && node.File.IsRename() {
return node.File.Names()
} else {
return []string{node.path}
}
return []string{node.path}
}
for _, prevNode := range prevNodes {

View File

@ -185,7 +185,7 @@ func (gui *Gui) handleCopySelectedSideContextItemToClipboardWithTruncation(maxWi
return err
}
truncatedItemId := utils.TruncateWithEllipsis(strings.Replace(itemId, "\n", " ", -1), 50)
truncatedItemId := utils.TruncateWithEllipsis(strings.ReplaceAll(itemId, "\n", " "), 50)
gui.c.Toast(fmt.Sprintf("'%s' %s", truncatedItemId, gui.c.Tr.CopiedToClipboard))

View File

@ -2,6 +2,7 @@ package gui
import (
goContext "context"
"errors"
"fmt"
"io"
"os"
@ -586,8 +587,8 @@ func (gui *Gui) resetState(startArgs appTypes.StartArgs) types.Context {
return initialContext(contextTree, startArgs)
}
func (self *Gui) getViewBufferManagerForView(view *gocui.View) *tasks.ViewBufferManager {
manager, ok := self.viewBufferManagerMap[view.Name()]
func (gui *Gui) getViewBufferManagerForView(view *gocui.View) *tasks.ViewBufferManager {
manager, ok := gui.viewBufferManagerMap[view.Name()]
if !ok {
return nil
}
@ -610,9 +611,9 @@ func initialScreenMode(startArgs appTypes.StartArgs, config config.AppConfigurer
return parseScreenModeArg(startArgs.ScreenMode)
} else if startArgs.FilterPath != "" || startArgs.GitArg != appTypes.GitArgNone {
return types.SCREEN_HALF
} else {
return parseScreenModeArg(config.GetUserConfig().Gui.ScreenMode)
}
return parseScreenModeArg(config.GetUserConfig().Gui.ScreenMode)
}
func parseScreenModeArg(screenModeArg string) types.ScreenMode {
@ -872,8 +873,7 @@ func (gui *Gui) RunAndHandleError(startArgs appTypes.StartArgs) error {
close(gui.stopChan)
switch err {
case gocui.ErrQuit:
if errors.Is(err, gocui.ErrQuit) {
if gui.c.State().GetRetainOriginalDir() {
if err := gui.helpers.RecordDirectory.RecordDirectory(gui.InitialDir); err != nil {
return err
@ -885,10 +885,9 @@ func (gui *Gui) RunAndHandleError(startArgs appTypes.StartArgs) error {
}
return nil
default:
return err
}
return err
}
return nil
@ -965,7 +964,7 @@ func (gui *Gui) runSubprocessWithSuspense(subprocess *oscommands.CmdObj) (bool,
return true, nil
}
func (gui *Gui) runSubprocess(cmdObj *oscommands.CmdObj) error { //nolint:unparam
func (gui *Gui) runSubprocess(cmdObj *oscommands.CmdObj) error {
gui.LogCommand(cmdObj.ToString(), true)
subprocess := cmdObj.GetCmd()

View File

@ -17,9 +17,9 @@ func (gui *Gui) informationStr() string {
donate := style.FgMagenta.Sprint(style.PrintHyperlink(gui.c.Tr.Donate, constants.Links.Donate))
askQuestion := style.FgYellow.Sprint(style.PrintHyperlink(gui.c.Tr.AskQuestion, constants.Links.Discussions))
return fmt.Sprintf("%s %s %s", donate, askQuestion, gui.Config.GetVersion())
} else {
return gui.Config.GetVersion()
}
return gui.Config.GetVersion()
}
func (gui *Gui) handleInfoClick() error {

View File

@ -45,27 +45,27 @@ func (gui *Gui) validateNotInFilterMode() bool {
}
// only to be called from the cheatsheet generate script. This mutates the Gui struct.
func (self *Gui) GetCheatsheetKeybindings() []*types.Binding {
self.g = &gocui.Gui{}
if err := self.createAllViews(); err != nil {
func (gui *Gui) GetCheatsheetKeybindings() []*types.Binding {
gui.g = &gocui.Gui{}
if err := gui.createAllViews(); err != nil {
panic(err)
}
// need to instantiate views
self.helpers = helpers.NewStubHelpers()
self.State = &GuiRepoState{}
self.State.Contexts = self.contextTree()
self.State.ContextMgr = NewContextMgr(self, self.State.Contexts)
self.resetHelpersAndControllers()
bindings, _ := self.GetInitialKeybindings()
gui.helpers = helpers.NewStubHelpers()
gui.State = &GuiRepoState{}
gui.State.Contexts = gui.contextTree()
gui.State.ContextMgr = NewContextMgr(gui, gui.State.Contexts)
gui.resetHelpersAndControllers()
bindings, _ := gui.GetInitialKeybindings()
return bindings
}
func (self *Gui) keybindingOpts() types.KeybindingsOpts {
config := self.c.UserConfig().Keybinding
func (gui *Gui) keybindingOpts() types.KeybindingsOpts {
config := gui.c.UserConfig().Keybinding
guards := types.KeybindingGuards{
OutsideFilterMode: self.outsideFilterMode,
NoPopupPanel: self.noPopupPanel,
OutsideFilterMode: gui.outsideFilterMode,
NoPopupPanel: gui.noPopupPanel,
}
return types.KeybindingsOpts{
@ -76,318 +76,318 @@ func (self *Gui) keybindingOpts() types.KeybindingsOpts {
}
// renaming receiver to 'self' to aid refactoring. Will probably end up moving all Gui handlers to this pattern eventually.
func (self *Gui) GetInitialKeybindings() ([]*types.Binding, []*gocui.ViewMouseBinding) {
opts := self.c.KeybindingsOpts()
func (gui *Gui) GetInitialKeybindings() ([]*types.Binding, []*gocui.ViewMouseBinding) {
opts := gui.c.KeybindingsOpts()
bindings := []*types.Binding{
{
ViewName: "",
Key: opts.GetKey(opts.Config.Universal.OpenRecentRepos),
Handler: opts.Guards.NoPopupPanel(self.helpers.Repos.CreateRecentReposMenu),
Description: self.c.Tr.SwitchRepo,
Handler: opts.Guards.NoPopupPanel(gui.helpers.Repos.CreateRecentReposMenu),
Description: gui.c.Tr.SwitchRepo,
},
{
ViewName: "",
Key: opts.GetKey(opts.Config.Universal.ScrollUpMain),
Handler: self.scrollUpMain,
Handler: gui.scrollUpMain,
Alternative: "fn+up/shift+k",
Description: self.c.Tr.ScrollUpMainWindow,
Description: gui.c.Tr.ScrollUpMainWindow,
},
{
ViewName: "",
Key: opts.GetKey(opts.Config.Universal.ScrollDownMain),
Handler: self.scrollDownMain,
Handler: gui.scrollDownMain,
Alternative: "fn+down/shift+j",
Description: self.c.Tr.ScrollDownMainWindow,
Description: gui.c.Tr.ScrollDownMainWindow,
},
{
ViewName: "",
Key: opts.GetKey(opts.Config.Universal.ScrollUpMainAlt1),
Modifier: gocui.ModNone,
Handler: self.scrollUpMain,
Handler: gui.scrollUpMain,
},
{
ViewName: "",
Key: opts.GetKey(opts.Config.Universal.ScrollDownMainAlt1),
Modifier: gocui.ModNone,
Handler: self.scrollDownMain,
Handler: gui.scrollDownMain,
},
{
ViewName: "",
Key: opts.GetKey(opts.Config.Universal.ScrollUpMainAlt2),
Modifier: gocui.ModNone,
Handler: self.scrollUpMain,
Handler: gui.scrollUpMain,
},
{
ViewName: "",
Key: opts.GetKey(opts.Config.Universal.ScrollDownMainAlt2),
Modifier: gocui.ModNone,
Handler: self.scrollDownMain,
Handler: gui.scrollDownMain,
},
{
ViewName: "files",
Key: opts.GetKey(opts.Config.Universal.CopyToClipboard),
Handler: self.handleCopySelectedSideContextItemToClipboard,
GetDisabledReason: self.getCopySelectedSideContextItemToClipboardDisabledReason,
Description: self.c.Tr.CopyPathToClipboard,
Handler: gui.handleCopySelectedSideContextItemToClipboard,
GetDisabledReason: gui.getCopySelectedSideContextItemToClipboardDisabledReason,
Description: gui.c.Tr.CopyPathToClipboard,
},
{
ViewName: "localBranches",
Key: opts.GetKey(opts.Config.Universal.CopyToClipboard),
Handler: self.handleCopySelectedSideContextItemToClipboard,
GetDisabledReason: self.getCopySelectedSideContextItemToClipboardDisabledReason,
Description: self.c.Tr.CopyBranchNameToClipboard,
Handler: gui.handleCopySelectedSideContextItemToClipboard,
GetDisabledReason: gui.getCopySelectedSideContextItemToClipboardDisabledReason,
Description: gui.c.Tr.CopyBranchNameToClipboard,
},
{
ViewName: "remoteBranches",
Key: opts.GetKey(opts.Config.Universal.CopyToClipboard),
Handler: self.handleCopySelectedSideContextItemToClipboard,
GetDisabledReason: self.getCopySelectedSideContextItemToClipboardDisabledReason,
Description: self.c.Tr.CopyBranchNameToClipboard,
Handler: gui.handleCopySelectedSideContextItemToClipboard,
GetDisabledReason: gui.getCopySelectedSideContextItemToClipboardDisabledReason,
Description: gui.c.Tr.CopyBranchNameToClipboard,
},
{
ViewName: "tags",
Key: opts.GetKey(opts.Config.Universal.CopyToClipboard),
Handler: self.handleCopySelectedSideContextItemToClipboard,
GetDisabledReason: self.getCopySelectedSideContextItemToClipboardDisabledReason,
Description: self.c.Tr.CopyTagToClipboard,
Handler: gui.handleCopySelectedSideContextItemToClipboard,
GetDisabledReason: gui.getCopySelectedSideContextItemToClipboardDisabledReason,
Description: gui.c.Tr.CopyTagToClipboard,
},
{
ViewName: "commits",
Key: opts.GetKey(opts.Config.Universal.CopyToClipboard),
Handler: self.handleCopySelectedSideContextItemCommitHashToClipboard,
GetDisabledReason: self.getCopySelectedSideContextItemToClipboardDisabledReason,
Description: self.c.Tr.CopyCommitHashToClipboard,
Handler: gui.handleCopySelectedSideContextItemCommitHashToClipboard,
GetDisabledReason: gui.getCopySelectedSideContextItemToClipboardDisabledReason,
Description: gui.c.Tr.CopyCommitHashToClipboard,
},
{
ViewName: "commits",
Key: opts.GetKey(opts.Config.Commits.ResetCherryPick),
Handler: self.helpers.CherryPick.Reset,
Description: self.c.Tr.ResetCherryPick,
Handler: gui.helpers.CherryPick.Reset,
Description: gui.c.Tr.ResetCherryPick,
},
{
ViewName: "reflogCommits",
Key: opts.GetKey(opts.Config.Universal.CopyToClipboard),
Handler: self.handleCopySelectedSideContextItemToClipboard,
GetDisabledReason: self.getCopySelectedSideContextItemToClipboardDisabledReason,
Description: self.c.Tr.CopyCommitHashToClipboard,
Handler: gui.handleCopySelectedSideContextItemToClipboard,
GetDisabledReason: gui.getCopySelectedSideContextItemToClipboardDisabledReason,
Description: gui.c.Tr.CopyCommitHashToClipboard,
},
{
ViewName: "subCommits",
Key: opts.GetKey(opts.Config.Universal.CopyToClipboard),
Handler: self.handleCopySelectedSideContextItemCommitHashToClipboard,
GetDisabledReason: self.getCopySelectedSideContextItemToClipboardDisabledReason,
Description: self.c.Tr.CopyCommitHashToClipboard,
Handler: gui.handleCopySelectedSideContextItemCommitHashToClipboard,
GetDisabledReason: gui.getCopySelectedSideContextItemToClipboardDisabledReason,
Description: gui.c.Tr.CopyCommitHashToClipboard,
},
{
ViewName: "information",
Key: gocui.MouseLeft,
Modifier: gocui.ModNone,
Handler: self.handleInfoClick,
Handler: gui.handleInfoClick,
},
{
ViewName: "commitFiles",
Key: opts.GetKey(opts.Config.Universal.CopyToClipboard),
Handler: self.handleCopySelectedSideContextItemToClipboard,
GetDisabledReason: self.getCopySelectedSideContextItemToClipboardDisabledReason,
Description: self.c.Tr.CopyPathToClipboard,
Handler: gui.handleCopySelectedSideContextItemToClipboard,
GetDisabledReason: gui.getCopySelectedSideContextItemToClipboardDisabledReason,
Description: gui.c.Tr.CopyPathToClipboard,
},
{
ViewName: "",
Key: opts.GetKey(opts.Config.Universal.ExtrasMenu),
Handler: opts.Guards.NoPopupPanel(self.handleCreateExtrasMenuPanel),
Description: self.c.Tr.OpenCommandLogMenu,
Tooltip: self.c.Tr.OpenCommandLogMenuTooltip,
Handler: opts.Guards.NoPopupPanel(gui.handleCreateExtrasMenuPanel),
Description: gui.c.Tr.OpenCommandLogMenu,
Tooltip: gui.c.Tr.OpenCommandLogMenuTooltip,
OpensMenu: true,
},
{
ViewName: "main",
Key: gocui.MouseWheelDown,
Handler: self.scrollDownMain,
Description: self.c.Tr.ScrollDown,
Handler: gui.scrollDownMain,
Description: gui.c.Tr.ScrollDown,
Alternative: "fn+up",
},
{
ViewName: "main",
Key: gocui.MouseWheelUp,
Handler: self.scrollUpMain,
Description: self.c.Tr.ScrollUp,
Handler: gui.scrollUpMain,
Description: gui.c.Tr.ScrollUp,
Alternative: "fn+down",
},
{
ViewName: "secondary",
Key: gocui.MouseWheelDown,
Modifier: gocui.ModNone,
Handler: self.scrollDownSecondary,
Handler: gui.scrollDownSecondary,
},
{
ViewName: "secondary",
Key: gocui.MouseWheelUp,
Modifier: gocui.ModNone,
Handler: self.scrollUpSecondary,
Handler: gui.scrollUpSecondary,
},
{
ViewName: "confirmation",
Key: opts.GetKey(opts.Config.Universal.PrevItem),
Modifier: gocui.ModNone,
Handler: self.scrollUpConfirmationPanel,
Handler: gui.scrollUpConfirmationPanel,
},
{
ViewName: "confirmation",
Key: opts.GetKey(opts.Config.Universal.NextItem),
Modifier: gocui.ModNone,
Handler: self.scrollDownConfirmationPanel,
Handler: gui.scrollDownConfirmationPanel,
},
{
ViewName: "confirmation",
Key: opts.GetKey(opts.Config.Universal.PrevItemAlt),
Modifier: gocui.ModNone,
Handler: self.scrollUpConfirmationPanel,
Handler: gui.scrollUpConfirmationPanel,
},
{
ViewName: "confirmation",
Key: opts.GetKey(opts.Config.Universal.NextItemAlt),
Modifier: gocui.ModNone,
Handler: self.scrollDownConfirmationPanel,
Handler: gui.scrollDownConfirmationPanel,
},
{
ViewName: "confirmation",
Key: gocui.MouseWheelUp,
Handler: self.scrollUpConfirmationPanel,
Handler: gui.scrollUpConfirmationPanel,
},
{
ViewName: "confirmation",
Key: gocui.MouseWheelDown,
Handler: self.scrollDownConfirmationPanel,
Handler: gui.scrollDownConfirmationPanel,
},
{
ViewName: "confirmation",
Key: opts.GetKey(opts.Config.Universal.NextPage),
Modifier: gocui.ModNone,
Handler: self.pageDownConfirmationPanel,
Handler: gui.pageDownConfirmationPanel,
},
{
ViewName: "confirmation",
Key: opts.GetKey(opts.Config.Universal.PrevPage),
Modifier: gocui.ModNone,
Handler: self.pageUpConfirmationPanel,
Handler: gui.pageUpConfirmationPanel,
},
{
ViewName: "confirmation",
Key: opts.GetKey(opts.Config.Universal.GotoTop),
Modifier: gocui.ModNone,
Handler: self.goToConfirmationPanelTop,
Handler: gui.goToConfirmationPanelTop,
},
{
ViewName: "confirmation",
Key: opts.GetKey(opts.Config.Universal.GotoTopAlt),
Modifier: gocui.ModNone,
Handler: self.goToConfirmationPanelTop,
Handler: gui.goToConfirmationPanelTop,
},
{
ViewName: "confirmation",
Key: opts.GetKey(opts.Config.Universal.GotoBottom),
Modifier: gocui.ModNone,
Handler: self.goToConfirmationPanelBottom,
Handler: gui.goToConfirmationPanelBottom,
},
{
ViewName: "confirmation",
Key: opts.GetKey(opts.Config.Universal.GotoBottomAlt),
Modifier: gocui.ModNone,
Handler: self.goToConfirmationPanelBottom,
Handler: gui.goToConfirmationPanelBottom,
},
{
ViewName: "submodules",
Key: opts.GetKey(opts.Config.Universal.CopyToClipboard),
Handler: self.handleCopySelectedSideContextItemToClipboard,
GetDisabledReason: self.getCopySelectedSideContextItemToClipboardDisabledReason,
Description: self.c.Tr.CopySubmoduleNameToClipboard,
Handler: gui.handleCopySelectedSideContextItemToClipboard,
GetDisabledReason: gui.getCopySelectedSideContextItemToClipboardDisabledReason,
Description: gui.c.Tr.CopySubmoduleNameToClipboard,
},
{
ViewName: "extras",
Key: gocui.MouseWheelUp,
Handler: self.scrollUpExtra,
Handler: gui.scrollUpExtra,
},
{
ViewName: "extras",
Key: gocui.MouseWheelDown,
Handler: self.scrollDownExtra,
Handler: gui.scrollDownExtra,
},
{
ViewName: "extras",
Tag: "navigation",
Key: opts.GetKey(opts.Config.Universal.PrevItemAlt),
Modifier: gocui.ModNone,
Handler: self.scrollUpExtra,
Handler: gui.scrollUpExtra,
},
{
ViewName: "extras",
Tag: "navigation",
Key: opts.GetKey(opts.Config.Universal.PrevItem),
Modifier: gocui.ModNone,
Handler: self.scrollUpExtra,
Handler: gui.scrollUpExtra,
},
{
ViewName: "extras",
Tag: "navigation",
Key: opts.GetKey(opts.Config.Universal.NextItem),
Modifier: gocui.ModNone,
Handler: self.scrollDownExtra,
Handler: gui.scrollDownExtra,
},
{
ViewName: "extras",
Tag: "navigation",
Key: opts.GetKey(opts.Config.Universal.NextItemAlt),
Modifier: gocui.ModNone,
Handler: self.scrollDownExtra,
Handler: gui.scrollDownExtra,
},
{
ViewName: "extras",
Key: opts.GetKey(opts.Config.Universal.NextPage),
Modifier: gocui.ModNone,
Handler: self.pageDownExtrasPanel,
Handler: gui.pageDownExtrasPanel,
},
{
ViewName: "extras",
Key: opts.GetKey(opts.Config.Universal.PrevPage),
Modifier: gocui.ModNone,
Handler: self.pageUpExtrasPanel,
Handler: gui.pageUpExtrasPanel,
},
{
ViewName: "extras",
Key: opts.GetKey(opts.Config.Universal.GotoTop),
Modifier: gocui.ModNone,
Handler: self.goToExtrasPanelTop,
Handler: gui.goToExtrasPanelTop,
},
{
ViewName: "extras",
Key: opts.GetKey(opts.Config.Universal.GotoTopAlt),
Modifier: gocui.ModNone,
Handler: self.goToExtrasPanelTop,
Handler: gui.goToExtrasPanelTop,
},
{
ViewName: "extras",
Key: opts.GetKey(opts.Config.Universal.GotoBottom),
Modifier: gocui.ModNone,
Handler: self.goToExtrasPanelBottom,
Handler: gui.goToExtrasPanelBottom,
},
{
ViewName: "extras",
Key: opts.GetKey(opts.Config.Universal.GotoBottomAlt),
Modifier: gocui.ModNone,
Handler: self.goToExtrasPanelBottom,
Handler: gui.goToExtrasPanelBottom,
},
{
ViewName: "extras",
Tag: "navigation",
Key: gocui.MouseLeft,
Modifier: gocui.ModNone,
Handler: self.handleFocusCommandLog,
Handler: gui.handleFocusCommandLog,
},
}
mouseKeybindings := []*gocui.ViewMouseBinding{}
for _, c := range self.State.Contexts.Flatten() {
for _, c := range gui.State.Contexts.Flatten() {
viewName := c.GetViewName()
for _, binding := range c.GetKeybindings(opts) {
// TODO: move all mouse keybindings into the mouse keybindings approach below
@ -402,15 +402,15 @@ func (self *Gui) GetInitialKeybindings() ([]*types.Binding, []*gocui.ViewMouseBi
{
ViewName: "",
Key: opts.GetKey(opts.Config.Universal.NextTab),
Handler: opts.Guards.NoPopupPanel(self.handleNextTab),
Description: self.c.Tr.NextTab,
Handler: opts.Guards.NoPopupPanel(gui.handleNextTab),
Description: gui.c.Tr.NextTab,
Tag: "navigation",
},
{
ViewName: "",
Key: opts.GetKey(opts.Config.Universal.PrevTab),
Handler: opts.Guards.NoPopupPanel(self.handlePrevTab),
Description: self.c.Tr.PrevTab,
Handler: opts.Guards.NoPopupPanel(gui.handlePrevTab),
Description: gui.c.Tr.PrevTab,
Tag: "navigation",
},
}...)
@ -418,12 +418,12 @@ func (self *Gui) GetInitialKeybindings() ([]*types.Binding, []*gocui.ViewMouseBi
return bindings, mouseKeybindings
}
func (self *Gui) GetInitialKeybindingsWithCustomCommands() ([]*types.Binding, []*gocui.ViewMouseBinding) {
func (gui *Gui) GetInitialKeybindingsWithCustomCommands() ([]*types.Binding, []*gocui.ViewMouseBinding) {
// if the search or filter prompt is open, we only want the keybindings for
// that context. It shouldn't be possible, for example, to open a menu while
// the prompt is showing; you first need to confirm or cancel the search/filter.
if currentContext := self.State.ContextMgr.Current(); currentContext.GetKey() == context.SEARCH_CONTEXT_KEY {
bindings := currentContext.GetKeybindings(self.c.KeybindingsOpts())
if currentContext := gui.State.ContextMgr.Current(); currentContext.GetKey() == context.SEARCH_CONTEXT_KEY {
bindings := currentContext.GetKeybindings(gui.c.KeybindingsOpts())
viewName := currentContext.GetViewName()
for _, binding := range bindings {
binding.ViewName = viewName
@ -431,8 +431,8 @@ func (self *Gui) GetInitialKeybindingsWithCustomCommands() ([]*types.Binding, []
return bindings, nil
}
bindings, mouseBindings := self.GetInitialKeybindings()
customBindings, err := self.CustomCommandsClient.GetCustomCommandKeybindings()
bindings, mouseBindings := gui.GetInitialKeybindings()
customBindings, err := gui.CustomCommandsClient.GetCustomCommandKeybindings()
if err != nil {
log.Fatal(err)
}

View File

@ -41,9 +41,8 @@ func GetKey(key string) types.Key {
binding, ok := config.KeyByLabel[strings.ToLower(key)]
if !ok {
log.Fatalf("Unrecognized key %s for keybinding. For permitted values see %s", strings.ToLower(key), constants.Links.Docs.CustomKeybindings)
} else {
return binding
}
return binding
} else if runeCount == 1 {
return []rune(key)[0]
}

View File

@ -50,9 +50,8 @@ func (s Selection) bounds(c *mergeConflict) (int, int) {
case TOP:
if c.hasAncestor() {
return c.start, c.ancestor
} else {
return c.start, c.target
}
return c.start, c.target
case MIDDLE:
return c.ancestor, c.target
case BOTTOM:
@ -72,7 +71,6 @@ func (s Selection) selected(c *mergeConflict, idx int) bool {
func availableSelections(c *mergeConflict) []Selection {
if c.hasAncestor() {
return []Selection{TOP, MIDDLE, BOTTOM}
} else {
return []Selection{TOP, BOTTOM}
}
return []Selection{TOP, BOTTOM}
}

View File

@ -25,9 +25,8 @@ func calculateNewOriginWithNeededAndWantedIdx(currentOrigin int, bufferHeight in
requiredChange := wantToSeeIdx - bottom
allowedChange := needToSeeIdx - origin
return origin + min(requiredChange, allowedChange)
} else {
return origin
}
return origin
}
func getNeedAndWantLineIdx(firstLineIdx int, lastLineIdx int, selectedLineIdx int, mode selectMode) (int, int) {
@ -37,9 +36,8 @@ func getNeedAndWantLineIdx(firstLineIdx int, lastLineIdx int, selectedLineIdx in
case RANGE:
if selectedLineIdx == firstLineIdx {
return firstLineIdx, lastLineIdx
} else {
return lastLineIdx, firstLineIdx
}
return lastLineIdx, firstLineIdx
case HUNK:
return firstLineIdx, lastLineIdx
default:

View File

@ -267,9 +267,8 @@ func (s *State) SelectedViewRange() (int, int) {
case RANGE:
if s.rangeStartLineIdx > s.selectedLineIdx {
return s.selectedLineIdx, s.rangeStartLineIdx
} else {
return s.rangeStartLineIdx, s.selectedLineIdx
}
return s.rangeStartLineIdx, s.selectedLineIdx
case LINE:
return s.selectedLineIdx, s.selectedLineIdx
default:

View File

@ -145,9 +145,8 @@ func GetCommitListDisplayStrings(
getGraphLine = func(idx int) string {
if idx >= graphOffset {
return graphLines[idx-graphOffset]
} else {
return ""
}
return ""
}
}
} else {
@ -305,9 +304,8 @@ func getBisectStatus(index int, commitHash string, bisectInfo *git_commands.Bise
} else {
if bisectBounds != nil && index >= bisectBounds.newIndex && index <= bisectBounds.oldIndex {
return BisectStatusCandidate
} else {
return BisectStatusNone
}
return BisectStatusNone
}
// should never land here

View File

@ -63,9 +63,8 @@ func commitFilePatchStatus(node *filetree.Node[models.CommitFile], tree *filetre
return patchBuilder.GetFileStatus(file.Path, tree.GetRef().RefName()) == patch.UNSELECTED
}) {
return patch.UNSELECTED
} else {
return patch.PART
}
return patch.PART
}
func renderAux[T any](
@ -185,9 +184,10 @@ func getFileLine(
func formatFileStatus(file *models.File, restColor style.TextStyle) string {
firstChar := file.ShortStatus[0:1]
firstCharCl := style.FgGreen
if firstChar == "?" {
switch firstChar {
case "?":
firstCharCl = theme.UnstagedChangesColor
} else if firstChar == " " {
case " ":
firstCharCl = restColor
}

View File

@ -177,7 +177,7 @@ func getBoxDrawingChars(up, down, left, right bool) (string, string) {
return "╶", "─"
} else if !up && !down && !left && !right {
return " ", " "
} else {
panic("should not be possible")
}
panic("should not be possible")
}

View File

@ -79,7 +79,7 @@ func RenderAux(pipeSets [][]Pipe, commits []*models.Commit, selectedCommitHashPt
wg := sync.WaitGroup{}
wg.Add(maxProcs)
for i := 0; i < maxProcs; i++ {
for i := range maxProcs {
go func() {
from := i * perProc
to := (i + 1) * perProc
@ -246,9 +246,8 @@ func getNextPipes(prevPipes []Pipe, commit *models.Commit, getStyle func(c *mode
for i := pipe.toPos; i > pos; i-- {
if takenSpots.Includes(int(i)) || traversedSpots.Includes(int(i)) {
break
} else {
last = i
}
last = i
}
newPipes = append(newPipes, Pipe{
fromPos: pipe.toPos,

View File

@ -579,7 +579,7 @@ func generateCommits(hashPool *utils.StringPool, count int) []*models.Commit {
parentCount := rnd.Intn(2) + 1
parentHashes := currentCommit.Parents()
for j := 0; j < parentCount; j++ {
for j := range parentCount {
reuseParent := rnd.Intn(6) != 1 && j <= len(pool)-1 && j != 0
var newParent *models.Commit
if reuseParent {

View File

@ -214,12 +214,10 @@ func RunTUI(raceDetector bool) {
err = g.MainLoop()
g.Close()
switch err {
case gocui.ErrQuit:
if errors.Is(err, gocui.ErrQuit) {
return
default:
log.Panicln(err)
}
log.Panicln(err)
}
type app struct {

View File

@ -33,7 +33,7 @@ func (self *CommitDescriptionPanelDriver) AddNewline() *CommitDescriptionPanelDr
func (self *CommitDescriptionPanelDriver) GoToBeginning() *CommitDescriptionPanelDriver {
numLines := len(self.getViewDriver().getView().BufferLines())
for i := 0; i < numLines; i++ {
for range numLines {
self.t.pressFast("<up>")
}

View File

@ -48,12 +48,12 @@ func RunTests(args RunTestArgs) error {
}
for _, test := range args.Tests {
args.TestWrapper(test, func() error { //nolint: thelper
args.TestWrapper(test, func() error {
paths := NewPaths(
filepath.Join(testDir, test.Name()),
)
for i := 0; i < args.MaxAttempts; i++ {
for i := range args.MaxAttempts {
err := runTest(test, args, paths, projectRootDir, gitVersion)
if err != nil {
if i == args.MaxAttempts-1 {

View File

@ -257,7 +257,7 @@ func (self *Shell) CreateNCommitsStartingAt(n, startIndex int) *Shell {
// Only to be used in demos, because the list might change and we don't want
// tests to break when it does.
func (self *Shell) CreateNCommitsWithRandomMessages(n int) *Shell {
for i := 0; i < n; i++ {
for i := range n {
file := RandomFiles[i]
self.CreateFileAndAdd(
file.Name,
@ -286,7 +286,7 @@ func (self *Shell) CreateRepoHistory() *Shell {
totalCommits := 0
// Generate commits
for i := 0; i < numInitialCommits; i++ {
for i := range numInitialCommits {
author := authors[i%numAuthors]
commitMessage := RandomCommitMessages[totalCommits%len(RandomCommitMessages)]
@ -296,7 +296,7 @@ func (self *Shell) CreateRepoHistory() *Shell {
}
// Generate branches and merges
for i := 0; i < numBranches; i++ {
for i := range numBranches {
// We'll have one author creating all the commits in the branch
author := authors[i%numAuthors]
branchName := RandomBranchNames[i%len(RandomBranchNames)]
@ -309,7 +309,7 @@ func (self *Shell) CreateRepoHistory() *Shell {
self.NewBranchFrom(branchName, fmt.Sprintf("master~%d", commitOffset))
numCommitsInBranch := rand.Intn(maxCommitsPerBranch) + 1
for j := 0; j < numCommitsInBranch; j++ {
for range numCommitsInBranch {
commitMessage := RandomCommitMessages[totalCommits%len(RandomCommitMessages)]
self.SetAuthor(author, "")

View File

@ -44,7 +44,7 @@ func (self *ViewDriver) Clear() *ViewDriver {
// clearing multiple times in case there's multiple lines
// (the clear button only clears a single line at a time)
maxAttempts := 100
for i := 0; i < maxAttempts+1; i++ {
for i := range maxAttempts + 1 {
if self.getView().Buffer() == "" {
break
}
@ -104,7 +104,7 @@ func (self *ViewDriver) ContainsLines(matchers ...*TextMatcher) *ViewDriver {
startIdx, endIdx := self.getSelectedRange()
for i := 0; i < len(lines)-len(matchers)+1; i++ {
for i := range len(lines) - len(matchers) + 1 {
matches := true
for j, matcher := range matchers {
checkIsSelected, matcher := matcher.checkIsSelected() // strip the IsSelected matcher out
@ -375,11 +375,11 @@ func (self *ViewDriver) Focus() *ViewDriver {
currentViewName := self.t.gui.CurrentContext().GetViewName()
currentViewTabIndex := lo.IndexOf(window.viewNames, currentViewName)
if tabIndex > currentViewTabIndex {
for i := 0; i < tabIndex-currentViewTabIndex; i++ {
for range tabIndex - currentViewTabIndex {
self.t.press(self.t.keys.Universal.NextTab)
}
} else if tabIndex < currentViewTabIndex {
for i := 0; i < currentViewTabIndex-tabIndex; i++ {
for range currentViewTabIndex - tabIndex {
self.t.press(self.t.keys.Universal.PrevTab)
}
}
@ -534,7 +534,7 @@ func (self *ViewDriver) NavigateToLine(matcher *TextMatcher) *ViewDriver {
keyPress = func() { self.SelectPreviousItem() }
}
for i := 0; i < maxNumKeyPresses; i++ {
for range maxNumKeyPresses {
keyPress()
idx := self.getSelectedLineIdx()
// It is important to use view.BufferLines() here and not lines, because it

View File

@ -18,7 +18,7 @@ func commonSetup(shell *Shell) {
repoStartDaysAgo := 100
for _, authorInfo := range authors {
for i := 0; i < authorInfo.numberOfCommits; i++ {
for i := range authorInfo.numberOfCommits {
authorEmail := strings.ToLower(strings.ReplaceAll(authorInfo.name, " ", ".")) + "@email.com"
commitMessage := fmt.Sprintf("commit %d", i)

View File

@ -114,7 +114,7 @@ func setDefaultVals(rootSchema, schema *jsonschema.Schema, defaults any) {
return
}
for i := 0; i < t.NumField(); i++ {
for i := range t.NumField() {
value := v.Field(i).Interface()
parentKey := t.Field(i).Name
@ -152,7 +152,7 @@ func isZeroValue(v any) bool {
case reflect.Ptr, reflect.Interface:
return rv.IsNil()
case reflect.Struct:
for i := 0; i < rv.NumField(); i++ {
for i := range rv.NumField() {
if !isZeroValue(rv.Field(i).Interface()) {
return false
}

View File

@ -129,7 +129,7 @@ func (self *Game) newFoodPos(snakePositions []Position) Position {
// arbitrarily setting a limit of attempts to place food
attemptLimit := 1000
for i := 0; i < attemptLimit; i++ {
for range attemptLimit {
newFoodPos := Position{self.randIntFn(self.width), self.randIntFn(self.height)}
if !lo.Contains(snakePositions, newFoodPos) {
@ -183,7 +183,7 @@ func (self *Game) getCells(state State) [][]CellType {
cells[pos.y][pos.x] = value
}
for i := 0; i < self.height; i++ {
for i := range self.height {
cells[i] = make([]CellType, self.width)
}

View File

@ -75,8 +75,8 @@ type LinesToRead struct {
Then func()
}
func (m *ViewBufferManager) GetTaskKey() string {
return m.taskKey
func (self *ViewBufferManager) GetTaskKey() string {
return self.taskKey
}
func NewViewBufferManager(
@ -260,7 +260,7 @@ func (self *ViewBufferManager) NewCmdTask(start func() (*exec.Cmd, io.Reader), p
callThen()
break outer
case line, ok = <-lineChan:
break
// process line below
}
loadingMutex.Lock()

View File

@ -167,7 +167,7 @@ func (d *BlankLineReader) Read(p []byte) (n int, err error) {
return 0, io.EOF
}
d.linesYielded += 1
d.linesYielded++
p[0] = '\n'
return 1, nil
}

View File

@ -25,7 +25,7 @@ type ColumnConfig struct {
func StringWidth(s string) int {
// We are intentionally not using a range loop here, because that would
// convert the characters to runes, which is unnecessary work in this case.
for i := 0; i < len(s); i++ {
for i := range len(s) {
if s[i] > unicode.MaxASCII {
return runewidth.StringWidth(s)
}
@ -44,9 +44,8 @@ func WithPadding(str string, padding int, alignment Alignment) string {
space := strings.Repeat(" ", padding-width)
if alignment == AlignLeft {
return str + space
} else {
return space + str
}
return space + str
}
// defaults to left-aligning each column. If you want to set the alignment of
@ -187,9 +186,8 @@ func TruncateWithEllipsis(str string, limit int) string {
func SafeTruncate(str string, limit int) string {
if len(str) > limit {
return str[0:limit]
} else {
return str
}
return str
}
const COMMIT_HASH_SHORT_SIZE = 8

View File

@ -11,7 +11,7 @@ import (
// currently we are also stripping \r's which may have adverse effects for
// windows users (but no issues have been raised yet)
func SplitLines(multilineString string) []string {
multilineString = strings.Replace(multilineString, "\r", "", -1)
multilineString = strings.ReplaceAll(multilineString, "\r", "")
if multilineString == "" || multilineString == "\n" {
return make([]string, 0)
}
@ -32,8 +32,8 @@ func SplitNul(str string) []string {
// NormalizeLinefeeds - Removes all Windows and Mac style line feeds
func NormalizeLinefeeds(str string) string {
str = strings.Replace(str, "\r\n", "\n", -1)
str = strings.Replace(str, "\r", "", -1)
str = strings.ReplaceAll(str, "\r\n", "\n")
str = strings.ReplaceAll(str, "\r", "")
return str
}

View File

@ -9,7 +9,7 @@ func TestOnceWriter(t *testing.T) {
innerWriter := bytes.NewBuffer(nil)
counter := 0
onceWriter := NewOnceWriter(innerWriter, func() {
counter += 1
counter++
})
_, _ = onceWriter.Write([]byte("hello"))
_, _ = onceWriter.Write([]byte("hello"))

View File

@ -41,7 +41,7 @@ func FindSubstringsFrom(pattern string, data fuzzy.Source) fuzzy.Matches {
result := fuzzy.Matches{}
outer:
for i := 0; i < data.Len(); i++ {
for i := range data.Len() {
s := data.String(i)
for _, sub := range substrings {
if !CaseAwareContains(s, sub) {

View File

@ -48,12 +48,12 @@ func TestThreadSafeMapConcurrentReadWrite(t *testing.T) {
m := NewThreadSafeMap[int, int]()
go func() {
for i := 0; i < 10000; i++ {
for range 10000 {
m.Set(0, 0)
}
}()
for i := 0; i < 10000; i++ {
for range 10000 {
m.Get(0)
}
}

View File

@ -45,9 +45,8 @@ func ModuloWithWrap(n, max int) int {
return n % max
} else if n < 0 {
return max + n
} else {
return n
}
return n
}
func FindStringSubmatch(str string, regexpStr string) (bool, []string) {

View File

@ -139,7 +139,7 @@ func walk(node *yaml.Node, path string, callback func(*yaml.Node, string)) error
}
}
case yaml.SequenceNode:
for i := 0; i < len(node.Content); i++ {
for i := range len(node.Content) {
childPath := fmt.Sprintf("%s[%d]", path, i)
err := walk(node.Content[i], childPath, callback)
if err != nil {

View File

@ -224,12 +224,10 @@ func TestTransformNode(t *testing.T) {
} else if node.ShortTag() == "!!str" {
// We have already transformed it,
return nil
} else {
return fmt.Errorf("Node was of bad type")
}
} else {
return fmt.Errorf("Node was not a scalar")
return fmt.Errorf("Node was of bad type")
}
return fmt.Errorf("Node was not a scalar")
}
tests := []struct {

12
scripts/lint.sh Executable file
View File

@ -0,0 +1,12 @@
#!/bin/sh
set -e
if [ ! -x ./.bin/golangci-lint ]; then
echo 'You need to install golangci-lint into .bin'
echo 'One way to do this is to run'
echo ' GOBIN=$(pwd)/.bin go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.2.1'
exit 1
fi
./.bin/golangci-lint run