From ffa336196a30f285d147ad33662374b53469d603 Mon Sep 17 00:00:00 2001 From: VERSE Date: Sat, 4 Jul 2026 19:44:38 +0700 Subject: [PATCH] chore: use go fix to enhance codebase (#29) This pull request modernizes the codebase by adopting Go 1.21+ features, including built-in functions like min and max, standard library iterators such as strings.SplitSeq and strings.FieldsSeq, utility functions like maps.Copy and slices.Contains, and string manipulation helpers like strings.Cut and strings.CutPrefix. Feedback is provided on a test file where the usage of strings.Builder can be further optimized to avoid unnecessary string allocations during concatenation. `go fix -diff ./...` --- commands/core/lookup.go | 17 ++++++-------- commands/fs/zoxide.go | 5 +---- commands/git/git.go | 2 +- commands/ops/docker.go | 6 ++--- commands/pkginstaller/pkgmgr.go | 2 +- commands/python/pip.go | 2 +- commands/runner/justfile.go | 8 +++---- commands/sys/ps.go | 2 +- integration/history.go | 13 +++++------ integration/overlay.go | 40 ++++++++------------------------- integration/shell/adapter.go | 12 +++++----- root/wrapper.go | 11 ++++----- tests/dev/git_test.go | 20 ++++++++--------- tests/dev/npm_ssh_test.go | 14 ++++++------ 14 files changed, 60 insertions(+), 94 deletions(-) diff --git a/commands/core/lookup.go b/commands/core/lookup.go index a7eb941..52d045b 100644 --- a/commands/core/lookup.go +++ b/commands/core/lookup.go @@ -1,6 +1,8 @@ package core import ( + "maps" + "slices" "strings" "sync" @@ -24,9 +26,7 @@ func GetAliasesCopy() map[string]string { shellAliasesMu.RLock() defer shellAliasesMu.RUnlock() cp := make(map[string]string, len(ShellAliases)) - for k, v := range ShellAliases { - cp[k] = v - } + maps.Copy(cp, ShellAliases) return cp } @@ -123,11 +123,8 @@ func Lookup(input string) []Suggestion { for _, sub := range currentSubs { match := sub.Name == tok if !match { - for _, a := range sub.Aliases { - if a == tok { - match = true - break - } + if slices.Contains(sub.Aliases, tok) { + match = true } } @@ -209,8 +206,8 @@ func Lookup(input string) []Suggestion { suggested = "\"" + suggested + "\"" } - // if the suggestion is a full path that includes - // words already in the command line (multi-word support), we replace + // if the suggestion is a full path that includes + // words already in the command line (multi-word support), we replace // the entire argument part by using prefix only finalCmd := "" if len(tokens) > depth+1 && strings.HasPrefix(g.Cmd, tokens[depth]) { diff --git a/commands/fs/zoxide.go b/commands/fs/zoxide.go index 2e86b83..8149366 100644 --- a/commands/fs/zoxide.go +++ b/commands/fs/zoxide.go @@ -51,10 +51,7 @@ func ZoxideGenerator() core.GeneratorFunc { home, _ := os.UserHomeDir() if fullQuery == "" { - limit := 20 - if len(dirs) < limit { - limit = len(dirs) - } + limit := min(len(dirs), 20) for i := 0; i < limit; i++ { path := dirs[i] display := strings.Replace(path, home, "~", 1) diff --git a/commands/git/git.go b/commands/git/git.go index c169789..f03416a 100644 --- a/commands/git/git.go +++ b/commands/git/git.go @@ -34,7 +34,7 @@ func GitCommitGenerator(tokens []string, _ string, _ string) []core.Suggestion { } var results []core.Suggestion - for _, line := range strings.Split(string(out), "\n") { + for line := range strings.SplitSeq(string(out), "\n") { line = strings.TrimSpace(line) if line == "" { continue diff --git a/commands/ops/docker.go b/commands/ops/docker.go index abb36d7..7da1c2f 100644 --- a/commands/ops/docker.go +++ b/commands/ops/docker.go @@ -22,7 +22,7 @@ func dockerContainerGenerator(tokens []string, _ string, _ string) []core.Sugges } var results []core.Suggestion - for _, line := range strings.Split(string(out), "\n") { + for line := range strings.SplitSeq(string(out), "\n") { line = strings.TrimSpace(line) if line == "" { continue @@ -45,7 +45,7 @@ func dockerRunningContainerGenerator(tokens []string, _ string, _ string) []core } var results []core.Suggestion - for _, line := range strings.Split(string(out), "\n") { + for line := range strings.SplitSeq(string(out), "\n") { line = strings.TrimSpace(line) if line == "" { continue @@ -69,7 +69,7 @@ func dockerImageGenerator(tokens []string, _ string, _ string) []core.Suggestion seen := make(map[string]bool) var results []core.Suggestion - for _, line := range strings.Split(string(out), "\n") { + for line := range strings.SplitSeq(string(out), "\n") { line = strings.TrimSpace(line) if line == "" || line == ":" || seen[line] { continue diff --git a/commands/pkginstaller/pkgmgr.go b/commands/pkginstaller/pkgmgr.go index ee773e7..bed9ff9 100644 --- a/commands/pkginstaller/pkgmgr.go +++ b/commands/pkginstaller/pkgmgr.go @@ -34,7 +34,7 @@ func installedPackageGenerator(pm string) core.GeneratorFunc { } var results []core.Suggestion - for _, line := range strings.Split(string(out), "\n") { + for line := range strings.SplitSeq(string(out), "\n") { line = strings.TrimSpace(line) if line == "" { continue diff --git a/commands/python/pip.go b/commands/python/pip.go index 931427f..e901091 100644 --- a/commands/python/pip.go +++ b/commands/python/pip.go @@ -25,7 +25,7 @@ func pipPackageGenerator(tokens []string, _ string, _ string) []core.Suggestion } var results []core.Suggestion - for _, line := range strings.Split(string(out), "\n") { + for line := range strings.SplitSeq(string(out), "\n") { line = strings.TrimSpace(line) if line == "" { continue diff --git a/commands/runner/justfile.go b/commands/runner/justfile.go index c248d11..9182c42 100644 --- a/commands/runner/justfile.go +++ b/commands/runner/justfile.go @@ -34,10 +34,10 @@ func init() { lastComment := "" for scanner.Scan() { line := strings.TrimSpace(scanner.Text()) - + // Handle comments - if strings.HasPrefix(line, "#") { - lastComment = strings.TrimSpace(strings.TrimPrefix(line, "#")) + if after, ok := strings.CutPrefix(line, "#"); ok { + lastComment = strings.TrimSpace(after) continue } @@ -55,7 +55,7 @@ func init() { seen[recipe] = true cmd := recipe - + desc := "just recipe" if lastComment != "" { desc = lastComment diff --git a/commands/sys/ps.go b/commands/sys/ps.go index 090717b..88ef065 100644 --- a/commands/sys/ps.go +++ b/commands/sys/ps.go @@ -22,7 +22,7 @@ func processGenerator(tokens []string, _ string, _ string) []core.Suggestion { seen := make(map[string]bool) var results []core.Suggestion - for _, line := range strings.Split(string(out), "\n") { + for line := range strings.SplitSeq(string(out), "\n") { line = strings.TrimSpace(line) if line == "" { continue diff --git a/integration/history.go b/integration/history.go index 7501e99..b27f7b1 100644 --- a/integration/history.go +++ b/integration/history.go @@ -95,8 +95,8 @@ func SearchHistory(query string, aliases map[string]string) ([]HistResult, error } } } else if shellName == "fish" { - if strings.HasPrefix(line, "- cmd: ") { - cmd = strings.TrimPrefix(line, "- cmd: ") + if after, ok := strings.CutPrefix(line, "- cmd: "); ok { + cmd = after } else { continue } @@ -128,10 +128,7 @@ func SearchHistory(query string, aliases map[string]string) ([]HistResult, error if query == "" { var results []HistResult - limit := 100 - if len(historyCache) < limit { - limit = len(historyCache) - } + limit := min(len(historyCache), 100) for i := 0; i < limit; i++ { cmd := historyCache[i] @@ -251,11 +248,11 @@ func SearchHistory(query string, aliases map[string]string) ([]HistResult, error if tI != tJ { return tI < tJ } - + if tI == 4 && results[i].FuzzyScore != results[j].FuzzyScore { return results[i].FuzzyScore > results[j].FuzzyScore } - + return results[i].ID > results[j].ID }) diff --git a/integration/overlay.go b/integration/overlay.go index b1820b6..8d31268 100644 --- a/integration/overlay.go +++ b/integration/overlay.go @@ -72,10 +72,7 @@ func ComputeCursorCol(data []byte) int { col = 0 } case 'G': - col = getParam(0, 1) - 1 - if col < 0 { - col = 0 - } + col = max(getParam(0, 1)-1, 0) } i = j + 1 continue @@ -313,7 +310,6 @@ func (o *Overlay) SetHistoryList(items []core.Suggestion, startAtBottom bool) st return "" } - func fixedWidth(s string, width int) string { if width <= 0 { return "" @@ -365,10 +361,7 @@ func (o *Overlay) RenderGhostText(buffer string, userNavigated bool) string { } ghostWidth := lipgloss.Width(ghostText) - padLen := o.LastGhostLen - ghostWidth - if padLen < 0 { - padLen = 0 - } + padLen := max(o.LastGhostLen-ghostWidth, 0) if o.LastGhostLen > 0 { padLen += 4 } @@ -410,10 +403,7 @@ func renderMatchedTitle(title, typed string, selected bool, w int) string { typedRunes := []rune(typed) displayRunes := []rune(display) - matchLen := len(typedRunes) - if matchLen > len(displayRunes) { - matchLen = len(displayRunes) - } + matchLen := min(len(typedRunes), len(displayRunes)) return match.Render(string(displayRunes[:matchLen])) + base.Render(string(displayRunes[matchLen:])) } @@ -453,10 +443,7 @@ func (o *Overlay) draw() string { s.WriteString("\0337") - windowSize := maxItems - if len(o.Items) < windowSize { - windowSize = len(o.Items) - } + windowSize := min(len(o.Items), maxItems) scrolloffUp := 1 if windowSize <= 3 { @@ -598,10 +585,7 @@ func (o *Overlay) draw() string { } tag := boxStyle.Render(" alias ") tw := lipgloss.Width(tag) - rem := descW - tw - 1 - if rem < 0 { - rem = 0 - } + rem := max(descW-tw-1, 0) desc = tag + bg.Render(" ") + bg.Foreground(descColor).Render(fixedWidth(it.Desc, rem)) case "history": boxStyle := lipgloss.NewStyle().Background(lipgloss.Color("#1a2d36")).Foreground(lipgloss.Color("#61ffca")) @@ -610,10 +594,7 @@ func (o *Overlay) draw() string { } tag := boxStyle.Render(" history ") tw := lipgloss.Width(tag) - rem := descW - tw - if rem < 0 { - rem = 0 - } + rem := max(descW-tw, 0) desc = tag + bg.Render(strings.Repeat(" ", rem)) case "system": boxStyle := lipgloss.NewStyle().Background(lipgloss.Color("#1e1d28")).Foreground(lipgloss.Color("#a277ff")) @@ -622,10 +603,7 @@ func (o *Overlay) draw() string { } tag := boxStyle.Render(" system ") tw := lipgloss.Width(tag) - rem := descW - tw - if rem < 0 { - rem = 0 - } + rem := max(descW-tw, 0) desc = tag + bg.Render(strings.Repeat(" ", rem)) default: desc = bg.Foreground(descColor).Render(fixedWidth(it.Desc, descW)) @@ -698,7 +676,7 @@ func (o *Overlay) Clear() string { s.WriteString("\033[?7l") s.WriteString("\0337") - for i := 0; i < maxItems+2; i++ { + for i := range maxItems + 2 { s.WriteString("\0338") fmt.Fprintf(&s, "\033[%dB", i+1) s.WriteString("\r\033[2K") @@ -736,7 +714,7 @@ func (o *Overlay) ClearAndDisable() string { s.WriteString("\0337") - for i := 0; i < maxItems+2; i++ { + for i := range maxItems + 2 { s.WriteString("\0338") fmt.Fprintf(&s, "\033[%dB", i+1) s.WriteString("\r\033[2K") diff --git a/integration/shell/adapter.go b/integration/shell/adapter.go index 8294993..3acf4b0 100644 --- a/integration/shell/adapter.go +++ b/integration/shell/adapter.go @@ -102,8 +102,8 @@ func ScanPosixAliases(files []string) map[string]string { func ParseAliases(data string) map[string]string { aliases := make(map[string]string) - lines := strings.Split(data, "\n") - for _, line := range lines { + lines := strings.SplitSeq(data, "\n") + for line := range lines { line = strings.TrimSpace(line) if !strings.HasPrefix(line, "alias ") { continue @@ -115,12 +115,12 @@ func ParseAliases(data string) map[string]string { pairs := SplitAliasTokens(body) for _, pair := range pairs { - eqIdx := strings.IndexByte(pair, '=') - if eqIdx < 0 { + before, after, ok := strings.Cut(pair, "=") + if !ok { continue } - key := strings.TrimSpace(pair[:eqIdx]) - val := strings.Trim(strings.TrimSpace(pair[eqIdx+1:]), `"'`) + key := strings.TrimSpace(before) + val := strings.Trim(strings.TrimSpace(after), `"'`) if key != "" && val != "" { aliases[key] = val } diff --git a/root/wrapper.go b/root/wrapper.go index 75883b3..f692ac0 100644 --- a/root/wrapper.go +++ b/root/wrapper.go @@ -170,7 +170,7 @@ func runWrapper() { out, errCmd := exec.CommandContext(ctx, "lsof", "-p", fmt.Sprintf("%d", c.Process.Pid), "-a", "-d", "cwd", "-F", "n").Output() cancel() if errCmd == nil { - for _, line := range strings.Split(string(out), "\n") { + for line := range strings.SplitSeq(string(out), "\n") { if strings.HasPrefix(line, "n") { cwd = strings.TrimSpace(line[1:]) linkErr = nil @@ -191,8 +191,8 @@ func runWrapper() { if logDir, pathErr := config.CachePath(); pathErr == nil { argsFile := filepath.Join(logDir, "reload-args") if data, readErr := os.ReadFile(argsFile); readErr == nil { - lines := strings.Split(string(data), "\n") - for _, line := range lines { + lines := strings.SplitSeq(string(data), "\n") + for line := range lines { trimmed := strings.TrimSpace(line) if trimmed != "" { execArgs = append(execArgs, trimmed) @@ -560,10 +560,7 @@ func runWrapper() { activeModeMu.RUnlock() results := MergeResults("", currentMode) if len(results) > 0 { - limit := 100 - if len(results) < limit { - limit = len(results) - } + limit := min(len(results), 100) var historyList []core.Suggestion if inputSlice[i+2] == 'A' { diff --git a/tests/dev/git_test.go b/tests/dev/git_test.go index 69a4e01..c6f199d 100644 --- a/tests/dev/git_test.go +++ b/tests/dev/git_test.go @@ -8,8 +8,8 @@ import ( "strings" "testing" - "github.com/versenilvis/iris/commands/core" _ "github.com/versenilvis/iris/commands" + "github.com/versenilvis/iris/commands/core" ) // setupGitRepo creates a real git repo in a temp dir with: @@ -188,7 +188,6 @@ func TestGitSuggestions(t *testing.T) { } }) - t.Run("branch with slash is suggested correctly", func(t *testing.T) { res := core.Lookup("git checkout ") found := false @@ -204,13 +203,14 @@ func TestGitSuggestions(t *testing.T) { t.Run("remote branches suggested for push", func(t *testing.T) { res := core.Lookup("git push origin ") - cmdStr := "" + var cmdStr strings.Builder for _, r := range res { - cmdStr += r.Cmd + " " + cmdStr.WriteString(r.Cmd) + cmdStr.WriteByte(' ') } // should have at least dev or main from branch list - if !strings.Contains(cmdStr, "dev") && !strings.Contains(cmdStr, "main") { - t.Errorf("git push origin should suggest local branches, got: %s", cmdStr) + if !strings.Contains(cmdStr.String(), "dev") && !strings.Contains(cmdStr.String(), "main") { + t.Errorf("git push origin should suggest local branches, got: %s", cmdStr.String()) } }) @@ -226,8 +226,8 @@ func TestGitSuggestions(t *testing.T) { res := core.Lookup("git checkout ") for _, r := range res { // the suggestion should not contain the active branch as a standalone word - parts := strings.Fields(r.Cmd) - for _, p := range parts { + parts := strings.FieldsSeq(r.Cmd) + for p := range parts { if p == activeBranch { t.Errorf("git checkout should not suggest active branch '%s', got: %s", activeBranch, r.Cmd) } @@ -365,8 +365,8 @@ func TestGitSuggestions(t *testing.T) { res := core.Lookup("git -c core.pager=cat checkout ") for _, r := range res { - parts := strings.Fields(r.Cmd) - for _, p := range parts { + parts := strings.FieldsSeq(r.Cmd) + for p := range parts { if p == activeBranch { t.Errorf("git -c core.pager=cat checkout should not suggest active branch '%s', got: %s", activeBranch, r.Cmd) } diff --git a/tests/dev/npm_ssh_test.go b/tests/dev/npm_ssh_test.go index 98d4b6b..b07979d 100644 --- a/tests/dev/npm_ssh_test.go +++ b/tests/dev/npm_ssh_test.go @@ -7,9 +7,9 @@ import ( "strings" "testing" + _ "github.com/versenilvis/iris/commands" "github.com/versenilvis/iris/commands/core" "github.com/versenilvis/iris/commands/js" - _ "github.com/versenilvis/iris/commands" ) func TestNpmScriptGenerator(t *testing.T) { @@ -20,11 +20,11 @@ func TestNpmScriptGenerator(t *testing.T) { pkg := map[string]any{ "name": "test-app", "scripts": map[string]string{ - "dev": "vite", - "build": "vite build", - "test": "vitest", - "lint": "eslint .", - "preview": "vite preview", + "dev": "vite", + "build": "vite build", + "test": "vitest", + "lint": "eslint .", + "preview": "vite preview", "typecheck": "tsc --noEmit", }, } @@ -173,7 +173,7 @@ func sshHostGeneratorFromPath(configPath string) []core.Suggestion { _ = scanner data, _ := os.ReadFile(configPath) - for _, line := range strings.Split(string(data), "\n") { + for line := range strings.SplitSeq(string(data), "\n") { line = strings.TrimSpace(line) if !strings.HasPrefix(strings.ToLower(line), "host ") { continue