From 4df8f87715790c6a9616051500d151e18c67237b Mon Sep 17 00:00:00 2001
From: fossdd
Date: Tue, 30 Apr 2024 17:17:42 +0000
Subject: [PATCH 01/36] Upgrade to Alpine Linux v3.19
Alpine v3.15 is out-of-date since 2023-11-01 and is not getting any security updates anymore: https://alpinelinux.org/releases/
---
Dockerfile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Dockerfile b/Dockerfile
index 594504468..6ddba8414 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -9,7 +9,7 @@ RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build
-FROM alpine:3.15
+FROM alpine:3.19
RUN apk add --no-cache -U git xdg-utils
WORKDIR /go/src/github.com/jesseduffield/lazygit/
COPY --from=build /go/src/github.com/jesseduffield/lazygit ./
From 08bd36ea783ca0709d2900220a38864c26b73109 Mon Sep 17 00:00:00 2001
From: Scott McKendry <39483124+scottmckendry@users.noreply.github.com>
Date: Sat, 2 Dec 2023 11:28:00 +1300
Subject: [PATCH 02/36] Add bicep & bicepparam icons
---
pkg/gui/presentation/icons/file_icons.go | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/pkg/gui/presentation/icons/file_icons.go b/pkg/gui/presentation/icons/file_icons.go
index 05832c55d..cdc284df5 100644
--- a/pkg/gui/presentation/icons/file_icons.go
+++ b/pkg/gui/presentation/icons/file_icons.go
@@ -98,6 +98,8 @@ var extIconMap = map[string]IconProperties{
".csv": {Icon: "\uf1c3", Color: 113}, //
".csx": {Icon: "\U000f031b", Color: 58}, //
".cxx": {Icon: "\ue61d", Color: 74}, //
+ ".bicep": {Icon: "\ue63b", Color: 32}, //
+ ".bicepparam": {Icon: "\ue63b", Color: 103}, //
".d": {Icon: "\ue7af", Color: 28}, //
".dart": {Icon: "\ue798", Color: 25}, //
".db": {Icon: "\uf1c0", Color: 188}, //
@@ -326,7 +328,12 @@ func patchFileIconsForNerdFontsV2() {
extIconMap[".vue"] = IconProperties{Icon: "\ufd42", Color: 113} // ﵂
}
-func IconForFile(name string, isSubmodule bool, isLinkedWorktree bool, isDirectory bool) IconProperties {
+func IconForFile(
+ name string,
+ isSubmodule bool,
+ isLinkedWorktree bool,
+ isDirectory bool,
+) IconProperties {
base := filepath.Base(name)
if icon, ok := nameIconMap[base]; ok {
return icon
From 2317dac7302227fc98e1434729efd0071845bcc8 Mon Sep 17 00:00:00 2001
From: Scott McKendry <39483124+scottmckendry@users.noreply.github.com>
Date: Thu, 21 Dec 2023 16:39:36 +1300
Subject: [PATCH 03/36] fix formatting
---
pkg/gui/presentation/icons/file_icons.go | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/pkg/gui/presentation/icons/file_icons.go b/pkg/gui/presentation/icons/file_icons.go
index cdc284df5..fe63cfa29 100644
--- a/pkg/gui/presentation/icons/file_icons.go
+++ b/pkg/gui/presentation/icons/file_icons.go
@@ -328,12 +328,7 @@ func patchFileIconsForNerdFontsV2() {
extIconMap[".vue"] = IconProperties{Icon: "\ufd42", Color: 113} // ﵂
}
-func IconForFile(
- name string,
- isSubmodule bool,
- isLinkedWorktree bool,
- isDirectory bool,
-) IconProperties {
+func IconForFile(name string, isSubmodule bool, isLinkedWorktree bool, isDirectory bool) IconProperties {
base := filepath.Base(name)
if icon, ok := nameIconMap[base]; ok {
return icon
From 5959f7bc8ef76d2a79e6c46ecd7039529337f2fc Mon Sep 17 00:00:00 2001
From: Elliot Cubit
Date: Tue, 9 Apr 2024 15:41:26 -0400
Subject: [PATCH 04/36] Allow setting a default name when creating new branches
---
docs/Config.md | 18 ++++++++++
pkg/config/user_config.go | 3 ++
pkg/gui/controllers/helpers/refs_helper.go | 4 +++
.../tests/commit/new_branch_with_prefix.go | 33 +++++++++++++++++++
pkg/integration/tests/test_list.go | 1 +
schema/config.json | 4 +++
6 files changed, 63 insertions(+)
create mode 100644 pkg/integration/tests/commit/new_branch_with_prefix.go
diff --git a/docs/Config.md b/docs/Config.md
index 358e7be5b..8506f7aed 100644
--- a/docs/Config.md
+++ b/docs/Config.md
@@ -323,6 +323,9 @@ git:
# Replace directive. E.g. for 'feature/AB-123' to start the commit message with 'AB-123 ' use "[$1] "
replace: ""
+ # See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#predefined-branch-name-prefix
+ branchPrefix: ""
+
# If true, parse emoji strings in commit messages e.g. render :rocket: as 🚀
# (This should really be under 'gui', not 'git')
parseEmoji: false
@@ -885,6 +888,21 @@ git:
replace: '[$1] '
```
+## Predefined branch name prefix
+
+In situations where certain naming pattern is used for branches, this can be used to populate new branch creation with a static prefix.
+
+Example:
+
+Some branches:
+- jsmith/AB-123
+- cwilson/AB-125
+
+```yaml
+git:
+ branchPrefix: "firstlast/"
+```
+
## Custom git log command
You can override the `git log` command that's used to render the log of the selected branch like so:
diff --git a/pkg/config/user_config.go b/pkg/config/user_config.go
index b5bccba45..c0613865e 100644
--- a/pkg/config/user_config.go
+++ b/pkg/config/user_config.go
@@ -236,6 +236,8 @@ type GitConfig struct {
CommitPrefix *CommitPrefixConfig `yaml:"commitPrefix"`
// See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#predefined-commit-message-prefix
CommitPrefixes map[string]CommitPrefixConfig `yaml:"commitPrefixes"`
+ // See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#predefined-branch-name-prefix
+ BranchPrefix string `yaml:"branchPrefix"`
// If true, parse emoji strings in commit messages e.g. render :rocket: as 🚀
// (This should really be under 'gui', not 'git')
ParseEmoji bool `yaml:"parseEmoji"`
@@ -750,6 +752,7 @@ func GetDefaultConfig() *UserConfig {
AllBranchesLogCmd: "git log --graph --all --color=always --abbrev-commit --decorate --date=relative --pretty=medium",
DisableForcePushing: false,
CommitPrefixes: map[string]CommitPrefixConfig(nil),
+ BranchPrefix: "",
ParseEmoji: false,
TruncateCopiedCommitHashesTo: 12,
},
diff --git a/pkg/gui/controllers/helpers/refs_helper.go b/pkg/gui/controllers/helpers/refs_helper.go
index 095e9848b..f471f57e2 100644
--- a/pkg/gui/controllers/helpers/refs_helper.go
+++ b/pkg/gui/controllers/helpers/refs_helper.go
@@ -274,6 +274,10 @@ func (self *RefsHelper) NewBranch(from string, fromFormattedName string, suggest
},
)
+ if suggestedBranchName == "" {
+ suggestedBranchName = self.c.UserConfig.Git.BranchPrefix
+ }
+
return self.c.Prompt(types.PromptOpts{
Title: message,
InitialContent: suggestedBranchName,
diff --git a/pkg/integration/tests/commit/new_branch_with_prefix.go b/pkg/integration/tests/commit/new_branch_with_prefix.go
new file mode 100644
index 000000000..21381630e
--- /dev/null
+++ b/pkg/integration/tests/commit/new_branch_with_prefix.go
@@ -0,0 +1,33 @@
+package commit
+
+import (
+ "github.com/jesseduffield/lazygit/pkg/config"
+ . "github.com/jesseduffield/lazygit/pkg/integration/components"
+)
+
+var NewBranchWithPrefix = NewIntegrationTest(NewIntegrationTestArgs{
+ Description: "Creating a new branch from a commit with a default name",
+ ExtraCmdArgs: []string{},
+ Skip: false,
+ SetupConfig: func(cfg *config.AppConfig) {
+ cfg.UserConfig.Git.BranchPrefix = "myprefix/"
+ },
+ SetupRepo: func(shell *Shell) {
+ shell.
+ EmptyCommit("commit 1")
+ },
+ Run: func(t *TestDriver, keys config.KeybindingConfig) {
+ t.Views().Commits().
+ Focus().
+ Lines(
+ Contains("commit 1").IsSelected(),
+ ).
+ SelectNextItem().
+ Press(keys.Universal.New).
+ Tap(func() {
+ branchName := "my-branch-name"
+ t.ExpectPopup().Prompt().Title(Contains("New branch name")).Type(branchName).Confirm()
+ t.Git().CurrentBranchName("myprefix/" + branchName)
+ })
+ },
+})
diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go
index ee547e950..cbd3471e5 100644
--- a/pkg/integration/tests/test_list.go
+++ b/pkg/integration/tests/test_list.go
@@ -92,6 +92,7 @@ var tests = []*components.IntegrationTest{
commit.History,
commit.HistoryComplex,
commit.NewBranch,
+ commit.NewBranchWithPrefix,
commit.PasteCommitMessage,
commit.PasteCommitMessageOverExisting,
commit.PreserveCommitMessage,
diff --git a/schema/config.json b/schema/config.json
index 580765c0f..cf67f78c8 100644
--- a/schema/config.json
+++ b/schema/config.json
@@ -638,6 +638,10 @@
"type": "object",
"description": "See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#predefined-commit-message-prefix"
},
+ "branchPrefix": {
+ "type": "string",
+ "description": "See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#predefined-branch-name-prefix"
+ },
"parseEmoji": {
"type": "boolean",
"description": "If true, parse emoji strings in commit messages e.g. render :rocket: as 🚀\n(This should really be under 'gui', not 'git')",
From ac30aee1b82e6e5e32fde0e24ef4ef5815643931 Mon Sep 17 00:00:00 2001
From: kyu08 <49891479+kyu08@users.noreply.github.com>
Date: Thu, 23 May 2024 23:58:13 +0900
Subject: [PATCH 05/36] Bump `actions/checkout`, `actions/setup-go`,
`actions/cache/restore`, `actions/cache/save`
---
.github/workflows/cd.yml | 4 ++--
.github/workflows/ci.yml | 28 ++++++++++++++--------------
.github/workflows/sponsors.yml | 2 +-
3 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml
index 823f2bc80..0b5b7d980 100644
--- a/.github/workflows/cd.yml
+++ b/.github/workflows/cd.yml
@@ -10,11 +10,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Unshallow repo
run: git fetch --prune --unshallow
- name: Setup Go
- uses: actions/setup-go@v4
+ uses: actions/setup-go@v5
with:
go-version: 1.22.x
- name: Run goreleaser
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index f6e2af260..64c890894 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -28,9 +28,9 @@ jobs:
GOFLAGS: -mod=vendor
steps:
- name: Checkout code
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Setup Go
- uses: actions/setup-go@v4
+ uses: actions/setup-go@v5
with:
go-version: 1.22.x
- name: Test code
@@ -61,11 +61,11 @@ jobs:
GOFLAGS: -mod=vendor
steps:
- name: Checkout code
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Restore Git cache
if: matrix.git-version != 'latest'
id: cache-git-restore
- uses: actions/cache/restore@v3
+ uses: actions/cache/restore@v4
with:
path: ~/git-${{matrix.git-version}}
key: ${{runner.os}}-git-${{matrix.git-version}}
@@ -82,12 +82,12 @@ jobs:
run: sudo make -C "$HOME/git-${{matrix.git-version}}" -j install
- name: Save Git cache
if: steps.cache-git-restore.outputs.cache-hit != 'true' && matrix.git-version != 'latest'
- uses: actions/cache/save@v3
+ uses: actions/cache/save@v4
with:
path: ~/git-${{matrix.git-version}}
key: ${{runner.os}}-git-${{matrix.git-version}}
- name: Setup Go
- uses: actions/setup-go@v4
+ uses: actions/setup-go@v5
with:
go-version: 1.22.x
- name: Print git version
@@ -111,9 +111,9 @@ jobs:
GOARCH: amd64
steps:
- name: Checkout code
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Setup Go
- uses: actions/setup-go@v4
+ uses: actions/setup-go@v5
with:
go-version: 1.22.x
- name: Build linux binary
@@ -138,9 +138,9 @@ jobs:
GOARCH: amd64
steps:
- name: Checkout code
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Setup Go
- uses: actions/setup-go@v4
+ uses: actions/setup-go@v5
with:
go-version: 1.22.x
- name: Check Vendor Directory
@@ -164,9 +164,9 @@ jobs:
GOFLAGS: -mod=vendor
steps:
- name: Checkout code
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Setup Go
- uses: actions/setup-go@v4
+ uses: actions/setup-go@v5
with:
go-version: 1.22.x
- name: Lint
@@ -192,10 +192,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout code
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Setup Go
- uses: actions/setup-go@v4
+ uses: actions/setup-go@v5
with:
go-version: 1.22.x
diff --git a/.github/workflows/sponsors.yml b/.github/workflows/sponsors.yml
index d49731b29..1737d6ce1 100644
--- a/.github/workflows/sponsors.yml
+++ b/.github/workflows/sponsors.yml
@@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout 🛎️
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Generate Sponsors 💖
uses: JamesIves/github-sponsors-readme-action@v1.2.2
From a5eec48b4b8f51054ef1b909df76cfd13ab78d46 Mon Sep 17 00:00:00 2001
From: Brandon
Date: Sat, 25 May 2024 15:47:15 -0700
Subject: [PATCH 06/36] Fix multi selection stage/discard not working for files
with substrings
---
pkg/gui/controllers/files_controller.go | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/pkg/gui/controllers/files_controller.go b/pkg/gui/controllers/files_controller.go
index 81d3f4cf0..39730ae09 100644
--- a/pkg/gui/controllers/files_controller.go
+++ b/pkg/gui/controllers/files_controller.go
@@ -1009,10 +1009,14 @@ func normalisedSelectedNodes(selectedNodes []*filetree.FileNode) []*filetree.Fil
func isDescendentOfSelectedNodes(node *filetree.FileNode, selectedNodes []*filetree.FileNode) bool {
for _, selectedNode := range selectedNodes {
+ if selectedNode.IsFile() {
+ continue
+ }
+
selectedNodePath := selectedNode.GetPath()
nodePath := node.GetPath()
- if strings.HasPrefix(nodePath, selectedNodePath) && nodePath != selectedNodePath {
+ if strings.HasPrefix(nodePath, selectedNodePath+"/") {
return true
}
}
From 2e5b570bb69e2cb1c1622b2ecb65ccb8c97cbe9a Mon Sep 17 00:00:00 2001
From: Brandon
Date: Sun, 26 May 2024 11:34:25 -0700
Subject: [PATCH 07/36] Add integration test
---
pkg/integration/components/shell.go | 11 +++++
.../tests/file/stage_renamed_range_select.go | 43 +++++++++++++++++++
pkg/integration/tests/test_list.go | 1 +
3 files changed, 55 insertions(+)
create mode 100644 pkg/integration/tests/file/stage_renamed_range_select.go
diff --git a/pkg/integration/components/shell.go b/pkg/integration/components/shell.go
index 01a9caf3a..e38e0cd3f 100644
--- a/pkg/integration/components/shell.go
+++ b/pkg/integration/components/shell.go
@@ -134,6 +134,17 @@ func (self *Shell) UpdateFile(path string, content string) *Shell {
return self
}
+func (self *Shell) Rename(path string, newPath string) *Shell {
+ fullPath := filepath.Join(self.dir, path)
+ newFullPath := filepath.Join(self.dir, newPath)
+ err := os.Rename(fullPath, newFullPath)
+ if err != nil {
+ self.fail(fmt.Sprintf("error renaming %s to %s\n%s", fullPath, newFullPath, err))
+ }
+
+ return self
+}
+
func (self *Shell) NewBranch(name string) *Shell {
return self.RunCommand([]string{"git", "checkout", "-b", name})
}
diff --git a/pkg/integration/tests/file/stage_renamed_range_select.go b/pkg/integration/tests/file/stage_renamed_range_select.go
new file mode 100644
index 000000000..472d8ef11
--- /dev/null
+++ b/pkg/integration/tests/file/stage_renamed_range_select.go
@@ -0,0 +1,43 @@
+package file
+
+import (
+ "github.com/jesseduffield/lazygit/pkg/config"
+ . "github.com/jesseduffield/lazygit/pkg/integration/components"
+)
+
+var StageRenamedRangeSelect = NewIntegrationTest(NewIntegrationTestArgs{
+ Description: "Stage a range of renamed files/folders using range select",
+ ExtraCmdArgs: []string{},
+ Skip: false,
+ SetupConfig: func(config *config.AppConfig) {
+ },
+ SetupRepo: func(shell *Shell) {
+ shell.CreateFileAndAdd("dir1/file-a", "A's content")
+ shell.CreateFileAndAdd("file-b", "B's content")
+ shell.Commit("first commit")
+ shell.Rename("dir1", "dir1_v2")
+ shell.Rename("file-b", "file-b_v2")
+ },
+ Run: func(t *TestDriver, keys config.KeybindingConfig) {
+ t.Views().Files().
+ IsFocused().
+ Lines(
+ Contains("▼ dir1").IsSelected(),
+ Contains(" D").Contains("file-a"),
+ Contains("▼ dir1_v2"),
+ Contains(" ??").Contains("file-a"),
+ Contains(" D").Contains("file-b"),
+ Contains("??").Contains("file-b_v2"),
+ ).
+ // Select everything
+ Press(keys.Universal.ToggleRangeSelect).
+ NavigateToLine(Contains("file-b_v2")).
+ // Stage
+ PressPrimaryAction().
+ Lines(
+ Contains("▼ dir1_v2"),
+ Contains(" R ").Contains("dir1/file-a → file-a"),
+ Contains("R ").Contains("file-b → file-b_v2").IsSelected(),
+ )
+ },
+})
diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go
index cbd3471e5..ff2634d07 100644
--- a/pkg/integration/tests/test_list.go
+++ b/pkg/integration/tests/test_list.go
@@ -161,6 +161,7 @@ var tests = []*components.IntegrationTest{
file.Gitignore,
file.RememberCommitMessageAfterFail,
file.StageRangeSelect,
+ file.StageRenamedRangeSelect,
filter_and_search.FilterCommitFiles,
filter_and_search.FilterFiles,
filter_and_search.FilterFuzzy,
From 38aa5b89ab10adeff83ae9e67d669268813bd2f1 Mon Sep 17 00:00:00 2001
From: Brandon
Date: Tue, 28 May 2024 18:09:07 -0700
Subject: [PATCH 08/36] Simplify integration test
---
pkg/integration/components/shell.go | 11 -----
.../tests/file/stage_children_range_select.go | 45 +++++++++++++++++++
.../tests/file/stage_renamed_range_select.go | 43 ------------------
pkg/integration/tests/test_list.go | 2 +-
4 files changed, 46 insertions(+), 55 deletions(-)
create mode 100644 pkg/integration/tests/file/stage_children_range_select.go
delete mode 100644 pkg/integration/tests/file/stage_renamed_range_select.go
diff --git a/pkg/integration/components/shell.go b/pkg/integration/components/shell.go
index e38e0cd3f..01a9caf3a 100644
--- a/pkg/integration/components/shell.go
+++ b/pkg/integration/components/shell.go
@@ -134,17 +134,6 @@ func (self *Shell) UpdateFile(path string, content string) *Shell {
return self
}
-func (self *Shell) Rename(path string, newPath string) *Shell {
- fullPath := filepath.Join(self.dir, path)
- newFullPath := filepath.Join(self.dir, newPath)
- err := os.Rename(fullPath, newFullPath)
- if err != nil {
- self.fail(fmt.Sprintf("error renaming %s to %s\n%s", fullPath, newFullPath, err))
- }
-
- return self
-}
-
func (self *Shell) NewBranch(name string) *Shell {
return self.RunCommand([]string{"git", "checkout", "-b", name})
}
diff --git a/pkg/integration/tests/file/stage_children_range_select.go b/pkg/integration/tests/file/stage_children_range_select.go
new file mode 100644
index 000000000..30a0a5e6b
--- /dev/null
+++ b/pkg/integration/tests/file/stage_children_range_select.go
@@ -0,0 +1,45 @@
+package file
+
+import (
+ "github.com/jesseduffield/lazygit/pkg/config"
+ . "github.com/jesseduffield/lazygit/pkg/integration/components"
+)
+
+var StageChildrenRangeSelect = NewIntegrationTest(NewIntegrationTestArgs{
+ Description: "Stage a range of files/folders and their children using range select",
+ ExtraCmdArgs: []string{},
+ Skip: false,
+ SetupConfig: func(config *config.AppConfig) {
+ },
+ SetupRepo: func(shell *Shell) {
+ shell.CreateFile("foo", "")
+ shell.CreateFile("foobar", "")
+ shell.CreateFile("baz/file", "")
+ shell.CreateFile("bazbam/file", "")
+ },
+ Run: func(t *TestDriver, keys config.KeybindingConfig) {
+ t.Views().Files().
+ IsFocused().
+ Lines(
+ Contains("▼ baz").IsSelected(),
+ Contains(" ??").Contains("file"),
+ Contains("▼ bazbam"),
+ Contains(" ??").Contains("file"),
+ Contains("??").Contains("foo"),
+ Contains("??").Contains("foobar"),
+ ).
+ // Select everything
+ Press(keys.Universal.ToggleRangeSelect).
+ NavigateToLine(Contains("foobar")).
+ // Stage
+ PressPrimaryAction().
+ Lines(
+ Contains("▼ baz").IsSelected(),
+ Contains(" A ").Contains("file").IsSelected(),
+ Contains("▼ bazbam").IsSelected(),
+ Contains(" A ").Contains("file").IsSelected(),
+ Contains("A ").Contains("foo").IsSelected(),
+ Contains("A ").Contains("foobar").IsSelected(),
+ )
+ },
+})
diff --git a/pkg/integration/tests/file/stage_renamed_range_select.go b/pkg/integration/tests/file/stage_renamed_range_select.go
deleted file mode 100644
index 472d8ef11..000000000
--- a/pkg/integration/tests/file/stage_renamed_range_select.go
+++ /dev/null
@@ -1,43 +0,0 @@
-package file
-
-import (
- "github.com/jesseduffield/lazygit/pkg/config"
- . "github.com/jesseduffield/lazygit/pkg/integration/components"
-)
-
-var StageRenamedRangeSelect = NewIntegrationTest(NewIntegrationTestArgs{
- Description: "Stage a range of renamed files/folders using range select",
- ExtraCmdArgs: []string{},
- Skip: false,
- SetupConfig: func(config *config.AppConfig) {
- },
- SetupRepo: func(shell *Shell) {
- shell.CreateFileAndAdd("dir1/file-a", "A's content")
- shell.CreateFileAndAdd("file-b", "B's content")
- shell.Commit("first commit")
- shell.Rename("dir1", "dir1_v2")
- shell.Rename("file-b", "file-b_v2")
- },
- Run: func(t *TestDriver, keys config.KeybindingConfig) {
- t.Views().Files().
- IsFocused().
- Lines(
- Contains("▼ dir1").IsSelected(),
- Contains(" D").Contains("file-a"),
- Contains("▼ dir1_v2"),
- Contains(" ??").Contains("file-a"),
- Contains(" D").Contains("file-b"),
- Contains("??").Contains("file-b_v2"),
- ).
- // Select everything
- Press(keys.Universal.ToggleRangeSelect).
- NavigateToLine(Contains("file-b_v2")).
- // Stage
- PressPrimaryAction().
- Lines(
- Contains("▼ dir1_v2"),
- Contains(" R ").Contains("dir1/file-a → file-a"),
- Contains("R ").Contains("file-b → file-b_v2").IsSelected(),
- )
- },
-})
diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go
index ff2634d07..bfc0fe786 100644
--- a/pkg/integration/tests/test_list.go
+++ b/pkg/integration/tests/test_list.go
@@ -160,8 +160,8 @@ var tests = []*components.IntegrationTest{
file.DiscardVariousChangesRangeSelect,
file.Gitignore,
file.RememberCommitMessageAfterFail,
+ file.StageChildrenRangeSelect,
file.StageRangeSelect,
- file.StageRenamedRangeSelect,
filter_and_search.FilterCommitFiles,
filter_and_search.FilterFiles,
filter_and_search.FilterFuzzy,
From eae76a97e9e0272895ff1d44d5f2e1f078d30a96 Mon Sep 17 00:00:00 2001
From: Bryan Honof
Date: Wed, 12 Jun 2024 14:24:32 +0200
Subject: [PATCH 09/36] docs: Add flox install
---
README.md | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/README.md b/README.md
index 3935f70ee..a600e500c 100644
--- a/README.md
+++ b/README.md
@@ -371,6 +371,16 @@ nix run nixpkgs#lazygit
Or you can add lazygit to you configuration.nix in the environment.systemPackages section.
More details can be found via NixOs search [page](https://search.nixos.org/).
+### Flox
+
+Lazygit can be installed into a Flox environment as follows.
+
+```sh
+flox install lazygit
+```
+
+More details about Flox can be found on [their website](https://flox.dev/).
+
### FreeBSD
```sh
From 8813587961c1d4e93a366b2a893996b6e36c328a Mon Sep 17 00:00:00 2001
From: Aleksei Larkov
Date: Sun, 9 Jun 2024 22:13:07 +0300
Subject: [PATCH 10/36] Add Token credential request handling
Asking for 2FA Token prompt when an additional authentication is configured for git over SSH
---
pkg/commands/oscommands/cmd_obj_runner.go | 2 ++
pkg/commands/oscommands/cmd_obj_runner_test.go | 8 ++++++++
pkg/gui/controllers/helpers/credentials_helper.go | 2 ++
pkg/i18n/english.go | 2 ++
4 files changed, 14 insertions(+)
diff --git a/pkg/commands/oscommands/cmd_obj_runner.go b/pkg/commands/oscommands/cmd_obj_runner.go
index 16257158e..1dd6ab2b2 100644
--- a/pkg/commands/oscommands/cmd_obj_runner.go
+++ b/pkg/commands/oscommands/cmd_obj_runner.go
@@ -284,6 +284,7 @@ const (
Username
Passphrase
PIN
+ Token
)
// Whenever we're asked for a password we just enter a newline, which will
@@ -376,6 +377,7 @@ func (self *cmdObjRunner) getCheckForCredentialRequestFunc() func([]byte) (Crede
`Username\s*for\s*'.+':`: Username,
`Enter\s*passphrase\s*for\s*key\s*'.+':`: Passphrase,
`Enter\s*PIN\s*for\s*.+\s*key\s*.+:`: PIN,
+ `.*2FA Token.*`: Token,
}
compiledPrompts := map[*regexp.Regexp]CredentialType{}
diff --git a/pkg/commands/oscommands/cmd_obj_runner_test.go b/pkg/commands/oscommands/cmd_obj_runner_test.go
index 31966cec1..c906cea3f 100644
--- a/pkg/commands/oscommands/cmd_obj_runner_test.go
+++ b/pkg/commands/oscommands/cmd_obj_runner_test.go
@@ -39,6 +39,8 @@ func TestProcessOutput(t *testing.T) {
return "passphrase"
case PIN:
return "pin"
+ case Token:
+ return "token"
default:
panic("unexpected credential type")
}
@@ -92,6 +94,12 @@ func TestProcessOutput(t *testing.T) {
output: "Enter PIN for key '123':",
expectedToWrite: "pin",
},
+ {
+ name: "2FA token prompt",
+ promptUserForCredential: defaultPromptUserForCredential,
+ output: "testuser 2FA Token (citadel)",
+ expectedToWrite: "token",
+ },
{
name: "username and password prompt",
promptUserForCredential: defaultPromptUserForCredential,
diff --git a/pkg/gui/controllers/helpers/credentials_helper.go b/pkg/gui/controllers/helpers/credentials_helper.go
index 20fb59052..6050c9be8 100644
--- a/pkg/gui/controllers/helpers/credentials_helper.go
+++ b/pkg/gui/controllers/helpers/credentials_helper.go
@@ -56,6 +56,8 @@ func (self *CredentialsHelper) getTitleAndMask(passOrUname oscommands.Credential
return self.c.Tr.CredentialsPassphrase, true
case oscommands.PIN:
return self.c.Tr.CredentialsPIN, true
+ case oscommands.Token:
+ return self.c.Tr.CredentialsToken, true
}
// should never land here
diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go
index 273dae530..62f429cde 100644
--- a/pkg/i18n/english.go
+++ b/pkg/i18n/english.go
@@ -36,6 +36,7 @@ type TranslationSet struct {
CredentialsPassword string
CredentialsPassphrase string
CredentialsPIN string
+ CredentialsToken string
PassUnameWrong string
Commit string
CommitTooltip string
@@ -1004,6 +1005,7 @@ func EnglishTranslationSet() *TranslationSet {
CredentialsPassword: "Password",
CredentialsPassphrase: "Enter passphrase for SSH key",
CredentialsPIN: "Enter PIN for SSH key",
+ CredentialsToken: "Enter Token for SSH key",
PassUnameWrong: "Password, passphrase and/or username wrong",
Commit: "Commit",
CommitTooltip: "Commit staged changes.",
From be21328c69a2436d99f80c9247852641b20a08cc Mon Sep 17 00:00:00 2001
From: Martin Kock
Date: Sat, 6 Jul 2024 21:59:10 +1000
Subject: [PATCH 11/36] Allow cycling between multiple log commands
- Introduced a new optional user config command, allBranchesLogCmds
- When pressing 'a' in the Status view, cycle between non-empty, non-identical log commands
- There will always be at least one command to run, since allBranhesLogCmd has a default
- Update documentation & write an integration test
- Update translation string
---
docs/Config.md | 3 ++-
docs/keybindings/Keybindings_en.md | 2 +-
pkg/commands/git_commands/branch.go | 16 +++++++++++-
pkg/config/user_config.go | 5 +++-
pkg/i18n/english.go | 2 +-
pkg/integration/tests/status/log_cmd.go | 33 +++++++++++++++++++++++++
pkg/integration/tests/test_list.go | 1 +
schema/config.json | 9 ++++++-
8 files changed, 65 insertions(+), 6 deletions(-)
create mode 100644 pkg/integration/tests/status/log_cmd.go
diff --git a/docs/Config.md b/docs/Config.md
index 8506f7aed..03501e8c2 100644
--- a/docs/Config.md
+++ b/docs/Config.md
@@ -306,7 +306,8 @@ git:
# Command used when displaying the current branch git log in the main window
branchLogCmd: git log --graph --color=always --abbrev-commit --decorate --date=relative --pretty=medium {{branchName}} --
- # Command used to display git log of all branches in the main window
+ # Command used to display git log of all branches in the main window.
+ # Deprecated: User `allBranchesLogCmds` instead.
allBranchesLogCmd: git log --graph --all --color=always --abbrev-commit --decorate --date=relative --pretty=medium
# If true, do not spawn a separate process when using GPG
diff --git a/docs/keybindings/Keybindings_en.md b/docs/keybindings/Keybindings_en.md
index 73104e994..eb88cb182 100644
--- a/docs/keybindings/Keybindings_en.md
+++ b/docs/keybindings/Keybindings_en.md
@@ -309,7 +309,7 @@ If you would instead like to start an interactive rebase from the selected commi
| `` e `` | Edit config file | Open file in external editor. |
| `` u `` | Check for update | |
| `` `` | Switch to a recent repo | |
-| `` a `` | Show all branch logs | |
+| `` a `` | Show/cycle all branch logs | |
## Sub-commits
diff --git a/pkg/commands/git_commands/branch.go b/pkg/commands/git_commands/branch.go
index bb065605c..6c9aa8740 100644
--- a/pkg/commands/git_commands/branch.go
+++ b/pkg/commands/git_commands/branch.go
@@ -7,10 +7,12 @@ import (
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
"github.com/jesseduffield/lazygit/pkg/utils"
"github.com/mgutz/str"
+ "github.com/samber/lo"
)
type BranchCommands struct {
*GitCommon
+ allBranchesLogCmdIndex uint8 // keeps track of current all branches log command
}
func NewBranchCommands(gitCommon *GitCommon) *BranchCommands {
@@ -244,5 +246,17 @@ func (self *BranchCommands) Merge(branchName string, opts MergeOpts) error {
}
func (self *BranchCommands) AllBranchesLogCmdObj() oscommands.ICmdObj {
- return self.cmd.New(str.ToArgv(self.UserConfig.Git.AllBranchesLogCmd)).DontLog()
+ // Only choose between non-empty, non-identical commands
+ candidates := lo.Uniq(lo.WithoutEmpty(append([]string{
+ self.UserConfig.Git.AllBranchesLogCmd,
+ },
+ self.UserConfig.Git.AllBranchesLogCmds...,
+ )))
+
+ n := len(candidates)
+
+ i := self.allBranchesLogCmdIndex
+ self.allBranchesLogCmdIndex = uint8((int(i) + 1) % n)
+
+ return self.cmd.New(str.ToArgv(candidates[i])).DontLog()
}
diff --git a/pkg/config/user_config.go b/pkg/config/user_config.go
index c0613865e..fbf513ea6 100644
--- a/pkg/config/user_config.go
+++ b/pkg/config/user_config.go
@@ -226,8 +226,11 @@ type GitConfig struct {
FetchAll bool `yaml:"fetchAll"`
// Command used when displaying the current branch git log in the main window
BranchLogCmd string `yaml:"branchLogCmd"`
- // Command used to display git log of all branches in the main window
+ // Command used to display git log of all branches in the main window.
+ // Deprecated: User `allBranchesLogCmds` instead.
AllBranchesLogCmd string `yaml:"allBranchesLogCmd"`
+ // Commands used to display git log of all branches in the main window, they will be cycled in order of appearance
+ AllBranchesLogCmds []string `yaml:"allBranchesLogCmds"`
// If true, do not spawn a separate process when using GPG
OverrideGpg bool `yaml:"overrideGpg"`
// If true, do not allow force pushes
diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go
index 62f429cde..d4c656202 100644
--- a/pkg/i18n/english.go
+++ b/pkg/i18n/english.go
@@ -1208,7 +1208,7 @@ func EnglishTranslationSet() *TranslationSet {
MergeBranchTooltip: "View options for merging the selected item into the current branch (regular merge, squash merge)",
ConfirmQuit: `Are you sure you want to quit?`,
SwitchRepo: `Switch to a recent repo`,
- AllBranchesLogGraph: `Show all branch logs`,
+ AllBranchesLogGraph: `Show/cycle all branch logs`,
UnsupportedGitService: `Unsupported git service`,
CreatePullRequest: `Create pull request`,
CopyPullRequestURL: `Copy pull request URL to clipboard`,
diff --git a/pkg/integration/tests/status/log_cmd.go b/pkg/integration/tests/status/log_cmd.go
new file mode 100644
index 000000000..7928cb1b6
--- /dev/null
+++ b/pkg/integration/tests/status/log_cmd.go
@@ -0,0 +1,33 @@
+package status
+
+import (
+ "github.com/jesseduffield/lazygit/pkg/config"
+ . "github.com/jesseduffield/lazygit/pkg/integration/components"
+)
+
+var LogCmd = NewIntegrationTest(NewIntegrationTestArgs{
+ Description: "Cycle between two different log commands in the Status view",
+ ExtraCmdArgs: []string{},
+ Skip: false,
+ SetupConfig: func(config *config.AppConfig) {
+ config.UserConfig.Git.AllBranchesLogCmd = `echo "view1"`
+ config.UserConfig.Git.AllBranchesLogCmds = []string{`echo "view2"`}
+ },
+ SetupRepo: func(shell *Shell) {},
+ Run: func(t *TestDriver, keys config.KeybindingConfig) {
+ t.Views().Status().
+ Focus().
+ Press(keys.Status.AllBranchesLogGraph)
+ t.Views().Main().Content(Contains("view1"))
+
+ t.Views().Status().
+ Focus().
+ Press(keys.Status.AllBranchesLogGraph)
+ t.Views().Main().Content(Contains("view2").DoesNotContain("view1"))
+
+ t.Views().Status().
+ Focus().
+ Press(keys.Status.AllBranchesLogGraph)
+ t.Views().Main().Content(Contains("view1").DoesNotContain("view2"))
+ },
+})
diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go
index bfc0fe786..ec24b9f5a 100644
--- a/pkg/integration/tests/test_list.go
+++ b/pkg/integration/tests/test_list.go
@@ -286,6 +286,7 @@ var tests = []*components.IntegrationTest{
status.ClickRepoNameToOpenReposMenu,
status.ClickToFocus,
status.ClickWorkingTreeStateToOpenRebaseOptionsMenu,
+ status.LogCmd,
status.ShowDivergenceFromBaseBranch,
submodule.Add,
submodule.Enter,
diff --git a/schema/config.json b/schema/config.json
index cf67f78c8..23e052f69 100644
--- a/schema/config.json
+++ b/schema/config.json
@@ -580,9 +580,16 @@
},
"allBranchesLogCmd": {
"type": "string",
- "description": "Command used to display git log of all branches in the main window",
+ "description": "Command used to display git log of all branches in the main window.\nDeprecated: User `allBranchesLogCmds` instead.",
"default": "git log --graph --all --color=always --abbrev-commit --decorate --date=relative --pretty=medium"
},
+ "allBranchesLogCmds": {
+ "items": {
+ "type": "string"
+ },
+ "type": "array",
+ "description": "Commands used to display git log of all branches in the main window, they will be cycled in order of appearance"
+ },
"overrideGpg": {
"type": "boolean",
"description": "If true, do not spawn a separate process when using GPG",
From 31456a8caaed8dc64bc6a6d5767fcb3008d10f0f Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Sat, 6 Jul 2024 12:08:18 +0000
Subject: [PATCH 12/36] README.md: Update Sponsors
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index a600e500c..f87a31840 100644
--- a/README.md
+++ b/README.md
@@ -46,7 +46,7 @@ A simple terminal UI for git commands
-















































































+


























































































## Elevator Pitch
From 7a670964cd3951c20e42a7b215f403f8ec4136c2 Mon Sep 17 00:00:00 2001
From: John Whitley
Date: Mon, 29 Jan 2024 16:58:35 -0800
Subject: [PATCH 13/36] Optimize number of early calls to GetRepoPaths
This change reduces the number of calls during application startup to
one, calling GetRepoPaths() earlier than previously and plumbing the
repoPaths struct around to achieve this end.
---
pkg/app/app.go | 24 ++++++----
pkg/commands/git_commands/repo_paths.go | 35 ++++++++++-----
pkg/commands/git_commands/repo_paths_test.go | 47 +++++++++++++++++---
pkg/commands/git_commands/status.go | 18 +-------
pkg/gui/dummies.go | 2 +-
pkg/gui/recent_repos_panel.go | 7 +--
6 files changed, 85 insertions(+), 48 deletions(-)
diff --git a/pkg/app/app.go b/pkg/app/app.go
index a16fbcc1f..e12461e28 100644
--- a/pkg/app/app.go
+++ b/pkg/app/app.go
@@ -14,7 +14,6 @@ import (
"github.com/spf13/afero"
appTypes "github.com/jesseduffield/lazygit/pkg/app/types"
- "github.com/jesseduffield/lazygit/pkg/commands"
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
"github.com/jesseduffield/lazygit/pkg/common"
@@ -119,7 +118,14 @@ func NewApp(config config.AppConfigurer, test integrationTypes.IntegrationTest,
return app, err
}
- showRecentRepos, err := app.setupRepo()
+ // If we're not in a repo, repoPaths will be nil. The error is moot for us
+ // at this stage, since we'll try to init a new repo in setupRepo(), below
+ repoPaths, err := git_commands.GetRepoPaths(app.OSCommand.Cmd, gitVersion)
+ if err != nil {
+ return app, err
+ }
+
+ showRecentRepos, err := app.setupRepo(repoPaths)
if err != nil {
return app, err
}
@@ -168,14 +174,16 @@ func openRecentRepo(app *App) bool {
return false
}
-func (app *App) setupRepo() (bool, error) {
+func (app *App) setupRepo(
+ repoPaths *git_commands.RepoPaths,
+) (bool, error) {
if env.GetGitDirEnv() != "" {
- // we've been given the git dir directly. We'll verify this dir when initializing our Git object
+ // we've been given the git dir directly. Skip setup
return false, nil
}
// if we are not in a git repo, we ask if we want to `git init`
- if err := commands.VerifyInGitRepo(app.OSCommand); err != nil {
+ if repoPaths == nil {
cwd, err := os.Getwd()
if err != nil {
return false, err
@@ -221,6 +229,7 @@ func (app *App) setupRepo() (bool, error) {
if err := app.OSCommand.Cmd.New(args).Run(); err != nil {
return false, err
}
+
return false, nil
}
@@ -238,10 +247,7 @@ func (app *App) setupRepo() (bool, error) {
}
// Run this afterward so that the previous repo creation steps can run without this interfering
- if isBare, err := git_commands.IsBareRepo(app.OSCommand); isBare {
- if err != nil {
- return false, err
- }
+ if repoPaths.IsBareRepo() {
fmt.Print(app.Tr.BareRepo)
diff --git a/pkg/commands/git_commands/repo_paths.go b/pkg/commands/git_commands/repo_paths.go
index b0e1970db..c2e77d446 100644
--- a/pkg/commands/git_commands/repo_paths.go
+++ b/pkg/commands/git_commands/repo_paths.go
@@ -2,6 +2,7 @@ package git_commands
import (
ioFs "io/fs"
+ "os"
"path"
"path/filepath"
"strings"
@@ -18,6 +19,7 @@ type RepoPaths struct {
repoPath string
repoGitDirPath string
repoName string
+ isBareRepo bool
}
var gitPathFormatVersion GitVersion = GitVersion{2, 31, 0, ""}
@@ -54,6 +56,10 @@ func (self *RepoPaths) RepoName() string {
return self.repoName
}
+func (self *RepoPaths) IsBareRepo() bool {
+ return self.isBareRepo
+}
+
// Returns the repo paths for a typical repo
func MockRepoPaths(currentPath string) *RepoPaths {
return &RepoPaths{
@@ -62,6 +68,7 @@ func MockRepoPaths(currentPath string) *RepoPaths {
repoPath: currentPath,
repoGitDirPath: path.Join(currentPath, ".git"),
repoName: "lazygit",
+ isBareRepo: false,
}
}
@@ -69,7 +76,19 @@ func GetRepoPaths(
cmd oscommands.ICmdObjBuilder,
version *GitVersion,
) (*RepoPaths, error) {
- gitDirOutput, err := callGitRevParse(cmd, version, "--show-toplevel", "--absolute-git-dir", "--git-common-dir", "--show-superproject-working-tree")
+ cwd, err := os.Getwd()
+ if err != nil {
+ return nil, err
+ }
+ return GetRepoPathsForDir(cwd, cmd, version)
+}
+
+func GetRepoPathsForDir(
+ dir string,
+ cmd oscommands.ICmdObjBuilder,
+ version *GitVersion,
+) (*RepoPaths, error) {
+ gitDirOutput, err := callGitRevParseWithDir(cmd, version, dir, "--show-toplevel", "--absolute-git-dir", "--git-common-dir", "--is-bare-repository", "--show-superproject-working-tree")
if err != nil {
return nil, err
}
@@ -84,13 +103,14 @@ func GetRepoPaths(
return nil, err
}
}
+ isBareRepo := gitDirResults[3] == "true"
// If we're in a submodule, --show-superproject-working-tree will return
- // a value, meaning gitDirResults will be length 4. In that case
+ // a value, meaning gitDirResults will be length 5. In that case
// return the worktree path as the repoPath. Otherwise we're in a
// normal repo or a worktree so return the parent of the git common
// dir (repoGitDirPath)
- isSubmodule := len(gitDirResults) == 4
+ isSubmodule := len(gitDirResults) == 5
var repoPath string
if isSubmodule {
@@ -106,17 +126,10 @@ func GetRepoPaths(
repoPath: repoPath,
repoGitDirPath: repoGitDirPath,
repoName: repoName,
+ isBareRepo: isBareRepo,
}, nil
}
-func callGitRevParse(
- cmd oscommands.ICmdObjBuilder,
- version *GitVersion,
- gitRevArgs ...string,
-) (string, error) {
- return callGitRevParseWithDir(cmd, version, "", gitRevArgs...)
-}
-
func callGitRevParseWithDir(
cmd oscommands.ICmdObjBuilder,
version *GitVersion,
diff --git a/pkg/commands/git_commands/repo_paths_test.go b/pkg/commands/git_commands/repo_paths_test.go
index 97cfc8119..9ee41a3fc 100644
--- a/pkg/commands/git_commands/repo_paths_test.go
+++ b/pkg/commands/git_commands/repo_paths_test.go
@@ -36,10 +36,12 @@ func TestGetRepoPaths(t *testing.T) {
"/path/to/repo/.git",
// --git-common-dir
"/path/to/repo/.git",
+ // --is-bare-repository
+ "false",
// --show-superproject-working-tree
}
runner.ExpectGitArgs(
- append(getRevParseArgs(), "--show-toplevel", "--absolute-git-dir", "--git-common-dir", "--show-superproject-working-tree"),
+ append(getRevParseArgs(), "--show-toplevel", "--absolute-git-dir", "--git-common-dir", "--is-bare-repository", "--show-superproject-working-tree"),
strings.Join(expectedOutput, "\n"),
nil)
},
@@ -50,6 +52,38 @@ func TestGetRepoPaths(t *testing.T) {
repoPath: "/path/to/repo",
repoGitDirPath: "/path/to/repo/.git",
repoName: "repo",
+ isBareRepo: false,
+ },
+ Err: nil,
+ },
+ {
+ Name: "bare repo",
+ BeforeFunc: func(runner *oscommands.FakeCmdObjRunner, getRevParseArgs argFn) {
+ // setup for main worktree
+ expectedOutput := []string{
+ // --show-toplevel
+ "/path/to/repo",
+ // --git-dir
+ "/path/to/bare_repo/bare.git",
+ // --git-common-dir
+ "/path/to/bare_repo/bare.git",
+ // --is-bare-repository
+ "true",
+ // --show-superproject-working-tree
+ }
+ runner.ExpectGitArgs(
+ append(getRevParseArgs(), "--show-toplevel", "--absolute-git-dir", "--git-common-dir", "--is-bare-repository", "--show-superproject-working-tree"),
+ strings.Join(expectedOutput, "\n"),
+ nil)
+ },
+ Path: "/path/to/repo",
+ Expected: &RepoPaths{
+ worktreePath: "/path/to/repo",
+ worktreeGitDirPath: "/path/to/bare_repo/bare.git",
+ repoPath: "/path/to/bare_repo",
+ repoGitDirPath: "/path/to/bare_repo/bare.git",
+ repoName: "bare_repo",
+ isBareRepo: true,
},
Err: nil,
},
@@ -63,11 +97,13 @@ func TestGetRepoPaths(t *testing.T) {
"/path/to/repo/.git/modules/submodule1",
// --git-common-dir
"/path/to/repo/.git/modules/submodule1",
+ // --is-bare-repository
+ "false",
// --show-superproject-working-tree
"/path/to/repo",
}
runner.ExpectGitArgs(
- append(getRevParseArgs(), "--show-toplevel", "--absolute-git-dir", "--git-common-dir", "--show-superproject-working-tree"),
+ append(getRevParseArgs(), "--show-toplevel", "--absolute-git-dir", "--git-common-dir", "--is-bare-repository", "--show-superproject-working-tree"),
strings.Join(expectedOutput, "\n"),
nil)
},
@@ -78,6 +114,7 @@ func TestGetRepoPaths(t *testing.T) {
repoPath: "/path/to/repo/submodule1",
repoGitDirPath: "/path/to/repo/.git/modules/submodule1",
repoName: "submodule1",
+ isBareRepo: false,
},
Err: nil,
},
@@ -85,7 +122,7 @@ func TestGetRepoPaths(t *testing.T) {
Name: "git rev-parse returns an error",
BeforeFunc: func(runner *oscommands.FakeCmdObjRunner, getRevParseArgs argFn) {
runner.ExpectGitArgs(
- append(getRevParseArgs(), "--show-toplevel", "--absolute-git-dir", "--git-common-dir", "--show-superproject-working-tree"),
+ append(getRevParseArgs(), "--show-toplevel", "--absolute-git-dir", "--git-common-dir", "--is-bare-repository", "--show-superproject-working-tree"),
"",
errors.New("fatal: invalid gitfile format: /path/to/repo/worktree2/.git"))
},
@@ -94,7 +131,7 @@ func TestGetRepoPaths(t *testing.T) {
Err: func(getRevParseArgs argFn) error {
args := strings.Join(getRevParseArgs(), " ")
return errors.New(
- fmt.Sprintf("'git %v --show-toplevel --absolute-git-dir --git-common-dir --show-superproject-working-tree' failed: fatal: invalid gitfile format: /path/to/repo/worktree2/.git", args),
+ 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),
)
},
},
@@ -120,7 +157,7 @@ func TestGetRepoPaths(t *testing.T) {
// prepare the filesystem for the scenario
s.BeforeFunc(runner, getRevParseArgs)
- repoPaths, err := GetRepoPaths(cmd, version)
+ repoPaths, err := GetRepoPathsForDir("", cmd, version)
// check the error and the paths
if s.Err != nil {
diff --git a/pkg/commands/git_commands/status.go b/pkg/commands/git_commands/status.go
index 65b29deef..0e0ef37fc 100644
--- a/pkg/commands/git_commands/status.go
+++ b/pkg/commands/git_commands/status.go
@@ -3,10 +3,8 @@ package git_commands
import (
"os"
"path/filepath"
- "strconv"
"strings"
- "github.com/jesseduffield/lazygit/pkg/commands/oscommands"
"github.com/jesseduffield/lazygit/pkg/commands/types/enums"
)
@@ -49,20 +47,8 @@ func (self *StatusCommands) WorkingTreeState() enums.RebaseMode {
return enums.REBASE_MODE_NONE
}
-func (self *StatusCommands) IsBareRepo() (bool, error) {
- return IsBareRepo(self.os)
-}
-
-func IsBareRepo(osCommand *oscommands.OSCommand) (bool, error) {
- res, err := osCommand.Cmd.New(
- NewGitCmd("rev-parse").Arg("--is-bare-repository").ToArgv(),
- ).DontLog().RunWithOutput()
- if err != nil {
- return false, err
- }
-
- // The command returns output with a newline, so we need to strip
- return strconv.ParseBool(strings.TrimSpace(res))
+func (self *StatusCommands) IsBareRepo() bool {
+ return self.repoPaths.isBareRepo
}
func (self *StatusCommands) IsInNormalRebase() (bool, error) {
diff --git a/pkg/gui/dummies.go b/pkg/gui/dummies.go
index 7bc36ff33..2350d215e 100644
--- a/pkg/gui/dummies.go
+++ b/pkg/gui/dummies.go
@@ -17,6 +17,6 @@ func NewDummyUpdater() *updates.Updater {
// NewDummyGui creates a new dummy GUI for testing
func NewDummyGui() *Gui {
newAppConfig := config.NewDummyAppConfig()
- dummyGui, _ := NewGui(utils.NewDummyCommon(), newAppConfig, &git_commands.GitVersion{}, NewDummyUpdater(), false, "", nil)
+ dummyGui, _ := NewGui(utils.NewDummyCommon(), newAppConfig, &git_commands.GitVersion{Major: 2, Minor: 0, Patch: 0}, NewDummyUpdater(), false, "", nil)
return dummyGui
}
diff --git a/pkg/gui/recent_repos_panel.go b/pkg/gui/recent_repos_panel.go
index acdb20672..0f2f2c704 100644
--- a/pkg/gui/recent_repos_panel.go
+++ b/pkg/gui/recent_repos_panel.go
@@ -8,12 +8,7 @@ import (
// updateRecentRepoList registers the fact that we opened lazygit in this repo,
// so that we can open the same repo via the 'recent repos' menu
func (gui *Gui) updateRecentRepoList() error {
- isBareRepo, err := gui.git.Status.IsBareRepo()
- if err != nil {
- return err
- }
-
- if isBareRepo {
+ if gui.git.Status.IsBareRepo() {
// we could totally do this but it would require storing both the git-dir and the
// worktree in our recent repos list, which is a change that would need to be
// backwards compatible
From 07fe828f60b2c091e038d76075ac7ed08588a9c2 Mon Sep 17 00:00:00 2001
From: Luke Swan
Date: Wed, 10 Jul 2024 00:47:22 +0300
Subject: [PATCH 14/36] Add initial test for non-matching branch name
---
.../commit_with_non_matching_branch_name.go | 38 +++++++++++++++++++
pkg/integration/tests/test_list.go | 1 +
2 files changed, 39 insertions(+)
create mode 100644 pkg/integration/tests/commit/commit_with_non_matching_branch_name.go
diff --git a/pkg/integration/tests/commit/commit_with_non_matching_branch_name.go b/pkg/integration/tests/commit/commit_with_non_matching_branch_name.go
new file mode 100644
index 000000000..490bbf9f8
--- /dev/null
+++ b/pkg/integration/tests/commit/commit_with_non_matching_branch_name.go
@@ -0,0 +1,38 @@
+package commit
+
+import (
+ "github.com/jesseduffield/lazygit/pkg/config"
+ . "github.com/jesseduffield/lazygit/pkg/integration/components"
+)
+
+var CommitWithNonMatchingBranchName = NewIntegrationTest(NewIntegrationTestArgs{
+ Description: "Commit with defined config commitPrefixes",
+ ExtraCmdArgs: []string{},
+ Skip: false,
+ SetupConfig: func(testConfig *config.AppConfig) {
+ testConfig.UserConfig.Git.CommitPrefix = &config.CommitPrefixConfig{
+ Pattern: "^\\w+\\/(\\w+-\\w+).*",
+ Replace: "[$1]: ",
+ }
+ },
+ SetupRepo: func(shell *Shell) {
+ shell.NewBranch("branchnomatch")
+ shell.CreateFile("test-commit-prefix", "This is foo bar")
+ },
+ Run: func(t *TestDriver, keys config.KeybindingConfig) {
+ t.Views().Commits().
+ IsEmpty()
+
+ t.Views().Files().
+ IsFocused().
+ PressPrimaryAction().
+ Press(keys.Files.CommitChanges)
+
+ t.ExpectPopup().CommitMessagePanel().
+ Title(Equals("Commit summary")).
+ /* EXPECTED:
+ InitialText(Equals(""))
+ ACTUAL: */
+ InitialText(Equals("branchnomatch"))
+ },
+})
diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go
index ec24b9f5a..fcc0b74bb 100644
--- a/pkg/integration/tests/test_list.go
+++ b/pkg/integration/tests/test_list.go
@@ -80,6 +80,7 @@ var tests = []*components.IntegrationTest{
commit.CommitSwitchToEditor,
commit.CommitWipWithPrefix,
commit.CommitWithGlobalPrefix,
+ commit.CommitWithNonMatchingBranchName,
commit.CommitWithPrefix,
commit.CreateAmendCommit,
commit.CreateTag,
From 968060a5ec13a7804301a1368899b756bcfb04b3 Mon Sep 17 00:00:00 2001
From: Luke Swan
Date: Sun, 30 Jun 2024 01:07:15 +0000
Subject: [PATCH 15/36] Ensure branch name matches pattern before replace
Amend test for non-matching branch name
---
pkg/gui/controllers/helpers/working_tree_helper.go | 8 ++++++--
.../tests/commit/commit_with_non_matching_branch_name.go | 3 ---
2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/pkg/gui/controllers/helpers/working_tree_helper.go b/pkg/gui/controllers/helpers/working_tree_helper.go
index a97639795..51a6bc553 100644
--- a/pkg/gui/controllers/helpers/working_tree_helper.go
+++ b/pkg/gui/controllers/helpers/working_tree_helper.go
@@ -152,12 +152,16 @@ func (self *WorkingTreeHelper) HandleCommitPress() error {
if commitPrefixConfig != nil {
prefixPattern := commitPrefixConfig.Pattern
prefixReplace := commitPrefixConfig.Replace
+ branchName := self.refHelper.GetCheckedOutRef().Name
rgx, err := regexp.Compile(prefixPattern)
if err != nil {
return fmt.Errorf("%s: %s", self.c.Tr.CommitPrefixPatternError, err.Error())
}
- prefix := rgx.ReplaceAllString(self.refHelper.GetCheckedOutRef().Name, prefixReplace)
- message = prefix
+
+ if rgx.MatchString(branchName) {
+ prefix := rgx.ReplaceAllString(branchName, prefixReplace)
+ message = prefix
+ }
}
}
diff --git a/pkg/integration/tests/commit/commit_with_non_matching_branch_name.go b/pkg/integration/tests/commit/commit_with_non_matching_branch_name.go
index 490bbf9f8..1075c7bb1 100644
--- a/pkg/integration/tests/commit/commit_with_non_matching_branch_name.go
+++ b/pkg/integration/tests/commit/commit_with_non_matching_branch_name.go
@@ -30,9 +30,6 @@ var CommitWithNonMatchingBranchName = NewIntegrationTest(NewIntegrationTestArgs{
t.ExpectPopup().CommitMessagePanel().
Title(Equals("Commit summary")).
- /* EXPECTED:
InitialText(Equals(""))
- ACTUAL: */
- InitialText(Equals("branchnomatch"))
},
})
From f0af42270ee86a1587e83e335096587d0e71f636 Mon Sep 17 00:00:00 2001
From: hasecilu
Date: Wed, 3 Apr 2024 15:52:35 -0600
Subject: [PATCH 16/36] Update link from unmaintained exa to maintained eza
---
pkg/gui/presentation/icons/file_icons.go | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/pkg/gui/presentation/icons/file_icons.go b/pkg/gui/presentation/icons/file_icons.go
index fe63cfa29..ee6027ffa 100644
--- a/pkg/gui/presentation/icons/file_icons.go
+++ b/pkg/gui/presentation/icons/file_icons.go
@@ -4,14 +4,16 @@ import (
"path/filepath"
)
-// https://github.com/ogham/exa/blob/master/src/output/icons.rs
+// NOTE: Visit next links for inspiration:
+// https://github.com/eza-community/eza/blob/main/src/output/icons.rs
+// https://github.com/nvim-tree/nvim-web-devicons/blob/master/lua/nvim-web-devicons/icons-default.lua
+
var (
DEFAULT_FILE_ICON = IconProperties{Icon: "\uf15b", Color: 241} //
DEFAULT_SUBMODULE_ICON = IconProperties{Icon: "\uf1d3", Color: 202} //
DEFAULT_DIRECTORY_ICON = IconProperties{Icon: "\uf07b", Color: 241} //
)
-// See https://github.com/nvim-tree/nvim-web-devicons/blob/master/lua/nvim-web-devicons/icons-default.lua
var nameIconMap = map[string]IconProperties{
".Trash": {Icon: "\uf1f8", Color: 241}, //
".atom": {Icon: "\ue764", Color: 241}, //
From cad4581d057616032c4cf9a4421a8666b7b8cc5f Mon Sep 17 00:00:00 2001
From: hasecilu
Date: Sat, 6 Apr 2024 20:31:25 -0600
Subject: [PATCH 17/36] Add icons for some file names
---
pkg/gui/presentation/icons/file_icons.go | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/pkg/gui/presentation/icons/file_icons.go b/pkg/gui/presentation/icons/file_icons.go
index ee6027ffa..db0151239 100644
--- a/pkg/gui/presentation/icons/file_icons.go
+++ b/pkg/gui/presentation/icons/file_icons.go
@@ -26,24 +26,41 @@ var nameIconMap = map[string]IconProperties{
".github": {Icon: "\uf408", Color: 241}, //
".gitignore": {Icon: "\uf1d3", Color: 202}, //
".gitmodules": {Icon: "\uf1d3", Color: 202}, //
+ ".mailmap": {Icon: "\uf1d3", Color: 202}, //
+ ".npmrc": {Icon: "\ue71e", Color: 197}, //
+ ".prettierrc": {Icon: "\ue6b4", Color: 33}, //
".rvm": {Icon: "\ue21e", Color: 160}, //
+ ".SRCINFO": {Icon: "\uf129", Color: 230}, //
".vimrc": {Icon: "\ue62b", Color: 28}, //
".vscode": {Icon: "\ue70c", Color: 39}, //
+ ".Xauthority": {Icon: "\uf369", Color: 196}, //
+ ".xinitrc": {Icon: "\uf369", Color: 196}, //
+ ".Xresources": {Icon: "\uf369", Color: 196}, //
+ ".xsession": {Icon: "\uf369", Color: 196}, //
".zshrc": {Icon: "\ue795", Color: 113}, //
+ "bin": {Icon: "\ue5fc", Color: 241}, //
"Cargo.lock": {Icon: "\ue7a8", Color: 216}, //
"Cargo.toml": {Icon: "\ue7a8", Color: 216}, //
- "bin": {Icon: "\ue5fc", Color: 241}, //
+ "COMMIT_EDITMSG": {Icon: "\ue702", Color: 239}, //
+ "compose.yaml": {Icon: "\uf308", Color: 68}, //
+ "compose.yml": {Icon: "\uf308", Color: 68}, //
"config": {Icon: "\ue5fc", Color: 241}, //
"docker-compose.yml": {Icon: "\uf308", Color: 68}, //
+ "docker-compose.yaml":{Icon: "\uf308", Color: 68}, //
"Dockerfile": {Icon: "\uf308", Color: 68}, //
"ds_store": {Icon: "\uf179", Color: 15}, //
+ "favicon.ico": {Icon: "\ue623", Color: 185}, //
+ "fp-info-cache": {Icon: "\uf49b", Color: 231}, //
+ "fp-lib-table": {Icon: "\uf34c", Color: 231}, //
"gitignore_global": {Icon: "\uf1d3", Color: 202}, //
+ "GNUmakefile": {Icon: "\ue779", Color: 66}, //
"go.mod": {Icon: "\ue627", Color: 74}, //
"go.sum": {Icon: "\ue627", Color: 74}, //
"gradle": {Icon: "\ue256", Color: 168}, //
"gruntfile.coffee": {Icon: "\ue611", Color: 166}, //
"gruntfile.js": {Icon: "\ue611", Color: 166}, //
"gruntfile.ls": {Icon: "\ue611", Color: 166}, //
+ "gtkrc": {Icon: "\uf362", Color: 231}, //
"gulpfile.coffee": {Icon: "\ue610", Color: 167}, //
"gulpfile.js": {Icon: "\ue610", Color: 167}, //
"gulpfile.ls": {Icon: "\ue610", Color: 168}, //
@@ -56,6 +73,9 @@ var nameIconMap = map[string]IconProperties{
"npmignore": {Icon: "\ue71e", Color: 197}, //
"PKGBUILD": {Icon: "\uf303", Color: 38}, //
"rubydoc": {Icon: "\ue73b", Color: 160}, //
+ "sym-lib-table": {Icon: "\uf34c", Color: 231}, //
+ "xorg.conf": {Icon: "\uf369", Color: 196}, //
+ "xsettingsd.conf": {Icon: "\uf369", Color: 196}, //
"yarn.lock": {Icon: "\ue6a7", Color: 74}, //
}
From 981f1fa7aa980a0a6adf5d89f7a2c141cb3c52dd Mon Sep 17 00:00:00 2001
From: hasecilu
Date: Sun, 7 Apr 2024 15:25:59 -0600
Subject: [PATCH 18/36] Add icons for some file extensions
---
pkg/gui/presentation/icons/file_icons.go | 132 +++++++++++++++++++++--
1 file changed, 124 insertions(+), 8 deletions(-)
diff --git a/pkg/gui/presentation/icons/file_icons.go b/pkg/gui/presentation/icons/file_icons.go
index db0151239..e98bb3961 100644
--- a/pkg/gui/presentation/icons/file_icons.go
+++ b/pkg/gui/presentation/icons/file_icons.go
@@ -80,32 +80,48 @@ var nameIconMap = map[string]IconProperties{
}
var extIconMap = map[string]IconProperties{
+ ".3gp": {Icon: "\uf03d", Color: 208}, //
+ ".3mf": {Icon: "\U000f01a7", Color: 102}, //
+ ".aac": {Icon: "\uf001", Color: 45}, //
".ai": {Icon: "\ue7b4", Color: 185}, //
".android": {Icon: "\ue70e", Color: 70}, //
".apk": {Icon: "\ue70e", Color: 70}, //
+ ".app": {Icon: "\ueae8", Color: 124}, //
".apple": {Icon: "\uf179", Color: 15}, //
+ ".applescript": {Icon: "\uf179", Color: 66}, //
+ ".ass": {Icon: "\U000f0a16", Color: 214}, //
".avi": {Icon: "\uf03d", Color: 140}, //
".avif": {Icon: "\uf1c5", Color: 140}, //
".avro": {Icon: "\ue60b", Color: 130}, //
".awk": {Icon: "\ue795", Color: 140}, //
+ ".azcli": {Icon: "\uebe8", Color: 32}, //
+ ".bak": {Icon: "\U000f006f", Color: 66}, //
".bash": {Icon: "\ue795", Color: 113}, //
".bash_history": {Icon: "\ue795", Color: 113}, //
".bash_profile": {Icon: "\ue795", Color: 113}, //
".bashrc": {Icon: "\ue795", Color: 113}, //
".bat": {Icon: "\uf17a", Color: 81}, //
".bats": {Icon: "\ue795", Color: 241}, //
+ ".bazel": {Icon: "\ue63a", Color: 113}, //
+ ".bib": {Icon: "\U000f125f", Color: 185}, //
+ ".blend": {Icon: "\U000f00ab", Color: 208}, //
+ ".blp": {Icon: "\U000f0ebe", Color: 68}, //
".bmp": {Icon: "\uf1c5", Color: 149}, //
+ ".brep": {Icon: "\U000f0eeb", Color: 101}, //
".bz": {Icon: "\uf410", Color: 239}, //
".bz2": {Icon: "\uf410", Color: 239}, //
+ ".bzl": {Icon: "\ue63a", Color: 113}, //
".c": {Icon: "\ue61e", Color: 111}, //
".c++": {Icon: "\ue61d", Color: 204}, //
".cab": {Icon: "\ue70f", Color: 241}, //
+ ".cache": {Icon: "\uf49b", Color: 231}, //
+ ".cast": {Icon: "\uf03d", Color: 208}, //
".cc": {Icon: "\ue61d", Color: 204}, //
".cfg": {Icon: "\ue615", Color: 255}, //
".class": {Icon: "\ue256", Color: 168}, //
".clj": {Icon: "\ue768", Color: 113}, //
".cljs": {Icon: "\ue76a", Color: 74}, //
- ".cls": {Icon: "\uf034", Color: 239}, //
+ ".cls": {Icon: "\ue69b", Color: 239}, //
".cmd": {Icon: "\ue70f", Color: 239}, //
".coffee": {Icon: "\uf0f4", Color: 185}, //
".conf": {Icon: "\ue615", Color: 66}, //
@@ -119,25 +135,32 @@ var extIconMap = map[string]IconProperties{
".css": {Icon: "\ue749", Color: 75}, //
".csv": {Icon: "\uf1c3", Color: 113}, //
".csx": {Icon: "\U000f031b", Color: 58}, //
+ ".cue": {Icon: "\U000f0cb9", Color: 211}, //
".cxx": {Icon: "\ue61d", Color: 74}, //
".bicep": {Icon: "\ue63b", Color: 32}, //
".bicepparam": {Icon: "\ue63b", Color: 103}, //
".d": {Icon: "\ue7af", Color: 28}, //
".dart": {Icon: "\ue798", Color: 25}, //
+ ".dconf": {Icon: "\ue706", Color: 188}, //
".db": {Icon: "\uf1c0", Color: 188}, //
".deb": {Icon: "\ue77d", Color: 88}, //
+ ".desktop": {Icon: "\uf108", Color: 54}, //
".diff": {Icon: "\uf440", Color: 241}, //
".djvu": {Icon: "\uf02d", Color: 241}, //
".dll": {Icon: "\ue70f", Color: 241}, //
- ".doc": {Icon: "\uf0219", Color: 26}, //
- ".docx": {Icon: "\uf0219", Color: 26}, //
+ ".doc": {Icon: "\U000f0219", Color: 26}, //
+ ".docx": {Icon: "\U000f0219", Color: 26}, //
+ ".dot": {Icon: "\U000f1049", Color: 24}, //
".ds_store": {Icon: "\uf179", Color: 15}, //
".DS_store": {Icon: "\uf179", Color: 15}, //
".dump": {Icon: "\uf1c0", Color: 188}, //
+ ".dwg": {Icon: "\U000f0eeb", Color: 101}, //
+ ".dxf": {Icon: "\U000f0eeb", Color: 101}, //
".ebook": {Icon: "\ue28b", Color: 241}, //
".ebuild": {Icon: "\uf30d", Color: 56}, //
".editorconfig": {Icon: "\ue615", Color: 241}, //
".ejs": {Icon: "\ue618", Color: 185}, //
+ ".elf": {Icon: "\ueae8", Color: 124}, //
".elm": {Icon: "\ue62c", Color: 74}, //
".env": {Icon: "\uf462", Color: 227}, //
".eot": {Icon: "\uf031", Color: 124}, //
@@ -147,13 +170,29 @@ var extIconMap = map[string]IconProperties{
".ex": {Icon: "\ue62d", Color: 140}, //
".exe": {Icon: "\uf17a", Color: 81}, //
".exs": {Icon: "\ue62d", Color: 140}, //
+ ".f90": {Icon: "\U000f121a", Color: 97}, //
+ ".fbx": {Icon: "\U000f01a7", Color: 102}, //
+ ".fcbak": {Icon: "\uf336", Color: 160}, //
+ ".fcmacro": {Icon: "\uf336", Color: 160}, //
+ ".fcmat": {Icon: "\uf336", Color: 160}, //
+ ".fcparam": {Icon: "\uf336", Color: 160}, //
+ ".fcscript": {Icon: "\uf336", Color: 160}, //
+ ".fcstd": {Icon: "\uf336", Color: 160}, //
+ ".fcstd1": {Icon: "\uf336", Color: 160}, //
+ ".fctb": {Icon: "\uf336", Color: 160}, //
+ ".fctl": {Icon: "\uf336", Color: 160}, //
".fish": {Icon: "\ue795", Color: 249}, //
".flac": {Icon: "\uf001", Color: 241}, //
+ ".flc": {Icon: "\uf031", Color: 255}, //
+ ".flf": {Icon: "\uf031", Color: 255}, //
".flv": {Icon: "\uf03d", Color: 241}, //
+ ".fnl": {Icon: "\ue6af", Color: 230}, //
".font": {Icon: "\uf031", Color: 241}, //
".fs": {Icon: "\ue7a7", Color: 74}, //
".fsi": {Icon: "\ue7a7", Color: 74}, //
".fsx": {Icon: "\ue7a7", Color: 74}, //
+ ".gcode": {Icon: "\U000f0af4", Color: 234}, //
+ ".gd": {Icon: "\ue65f", Color: 66}, //
".gdoc": {Icon: "\uf1c2", Color: 40}, //
".gem": {Icon: "\ue21e", Color: 160}, //
".gemfile": {Icon: "\ue21e", Color: 160}, //
@@ -165,23 +204,37 @@ var extIconMap = map[string]IconProperties{
".gitignore": {Icon: "\uf1d3", Color: 202}, //
".gitmodules": {Icon: "\uf1d3", Color: 202}, //
".go": {Icon: "\ue627", Color: 74}, //
+ ".godot": {Icon: "\ue65f", Color: 66}, //
+ ".gql": {Icon: "\uf20e", Color: 199}, //
+ ".graphql": {Icon: "\uf20e", Color: 199}, //
".gradle": {Icon: "\ue256", Color: 168}, //
+ ".gresource": {Icon: "\uf362", Color: 231}, //
".groovy": {Icon: "\ue775", Color: 24}, //
".gsheet": {Icon: "\uf1c3", Color: 10}, //
".gslides": {Icon: "\uf1c4", Color: 226}, //
".guardfile": {Icon: "\ue21e", Color: 241}, //
+ ".gv": {Icon: "\U000f1049", Color: 24}, //
".gz": {Icon: "\uf410", Color: 241}, //
".h": {Icon: "\uf0fd", Color: 140}, //
".hbs": {Icon: "\ue60f", Color: 202}, //
+ ".hc": {Icon: "\U000f00a2", Color: 227}, //
+ ".hex": {Icon: "\U000f12a7", Color: 27}, //
+ ".hh": {Icon: "\uf0fd", Color: 140}, //
".hpp": {Icon: "\uf0fd", Color: 140}, //
".hs": {Icon: "\ue777", Color: 140}, //
".htm": {Icon: "\uf13b", Color: 196}, //
".html": {Icon: "\uf13b", Color: 196}, //
".hxx": {Icon: "\uf0fd", Color: 140}, //
".ico": {Icon: "\uf1c5", Color: 185}, //
+ ".ifc": {Icon: "\U000f0eeb", Color: 101}, //
+ ".ige": {Icon: "\U000f0eeb", Color: 101}, //
+ ".iges": {Icon: "\U000f0eeb", Color: 101}, //
+ ".igs": {Icon: "\U000f0eeb", Color: 101}, //
".image": {Icon: "\uf1c5", Color: 185}, //
".iml": {Icon: "\ue7b5", Color: 239}, //
+ ".info": {Icon: "\uf129", Color: 230}, //
".ini": {Icon: "\uf17a", Color: 81}, //
+ ".ino": {Icon: "\uf34b", Color: 73}, //
".ipynb": {Icon: "\ue606", Color: 214}, //
".iso": {Icon: "\ue271", Color: 239}, //
".j2c": {Icon: "\uf1c5", Color: 239}, //
@@ -203,25 +256,46 @@ var extIconMap = map[string]IconProperties{
".json": {Icon: "\ue60b", Color: 185}, //
".jsx": {Icon: "\ue7ba", Color: 45}, //
".jxl": {Icon: "\uf1c5", Color: 241}, //
+ ".kdenlive": {Icon: "\uf33c", Color: 110}, //
+ ".kdenlivetitle": {Icon: "\uf33c", Color: 110}, //
+ ".kicad_dru": {Icon: "\uf34c", Color: 231}, //
+ ".kicad_mod": {Icon: "\uf34c", Color: 231}, //
+ ".kicad_pcb": {Icon: "\uf34c", Color: 231}, //
+ ".kicad_prl": {Icon: "\uf34c", Color: 231}, //
+ ".kicad_pro": {Icon: "\uf34c", Color: 231}, //
+ ".kicad_sch": {Icon: "\uf34c", Color: 231}, //
+ ".kicad_sym": {Icon: "\uf34c", Color: 231}, //
+ ".kicad_wks": {Icon: "\uf34c", Color: 231}, //
+ ".kpp": {Icon: "\uf33d", Color: 201}, //
+ ".kra": {Icon: "\uf33d", Color: 201}, //
+ ".krz": {Icon: "\uf33d", Color: 201}, //
".ksh": {Icon: "\ue795", Color: 241}, //
".kt": {Icon: "\ue634", Color: 99}, //
".kts": {Icon: "\ue634", Color: 99}, //
- ".latex": {Icon: "\uf034", Color: 241}, //
+ ".latex": {Icon: "\ue69b", Color: 241}, //
+ ".lck": {Icon: "\ue672", Color: 250}, //
".less": {Icon: "\ue758", Color: 54}, //
".lhs": {Icon: "\ue777", Color: 140}, //
".license": {Icon: "\U000f0219", Color: 185}, //
".localized": {Icon: "\uf179", Color: 15}, //
".lock": {Icon: "\uf023", Color: 241}, //
- ".log": {Icon: "\uf18d", Color: 188}, //
+ ".log": {Icon: "\uf4ed", Color: 188}, //
+ ".lrc": {Icon: "\U000f0a16", Color: 214}, //
".lua": {Icon: "\ue620", Color: 74}, //
+ ".luac": {Icon: "\ue620", Color: 74}, //
+ ".luau": {Icon: "\ue620", Color: 74}, //
".lz": {Icon: "\uf410", Color: 241}, //
".lz4": {Icon: "\uf410", Color: 241}, //
".lzh": {Icon: "\uf410", Color: 241}, //
".lzma": {Icon: "\uf410", Color: 241}, //
".lzo": {Icon: "\uf410", Color: 241}, //
".m": {Icon: "\ue61e", Color: 111}, //
- ".mm": {Icon: "\ue61d", Color: 111}, //
+ ".m3u": {Icon: "\U000f0cb9", Color: 211}, //
+ ".m3u8": {Icon: "\U000f0cb9", Color: 211}, //
".m4a": {Icon: "\uf001", Color: 239}, //
+ ".m4v": {Icon: "\uf03d", Color: 208}, //
+ ".magnet": {Icon: "\uf076", Color: 124}, //
+ ".makefile": {Icon: "\ue779", Color: 66}, //
".markdown": {Icon: "\uf48a", Color: 74}, //
".md": {Icon: "\uf48a", Color: 74}, //
".mdx": {Icon: "\uf48a", Color: 74}, //
@@ -229,27 +303,37 @@ var extIconMap = map[string]IconProperties{
".mk": {Icon: "\ue795", Color: 241}, //
".mkd": {Icon: "\uf48a", Color: 74}, //
".mkv": {Icon: "\uf03d", Color: 241}, //
+ ".mm": {Icon: "\ue61d", Color: 111}, //
".mobi": {Icon: "\ue28b", Color: 241}, //
".mov": {Icon: "\uf03d", Color: 241}, //
".mp3": {Icon: "\uf001", Color: 241}, //
".mp4": {Icon: "\uf03d", Color: 241}, //
".msi": {Icon: "\ue70f", Color: 241}, //
".mustache": {Icon: "\ue60f", Color: 241}, //
+ ".nfo": {Icon: "\uf129", Color: 230}, //
".nix": {Icon: "\uf313", Color: 111}, //
".node": {Icon: "\U000f0399", Color: 197}, //
".npmignore": {Icon: "\ue71e", Color: 197}, //
+ ".obj": {Icon: "\U000f01a7", Color: 102}, //
".odp": {Icon: "\uf1c4", Color: 241}, //
".ods": {Icon: "\uf1c3", Color: 241}, //
".odt": {Icon: "\uf1c2", Color: 241}, //
".ogg": {Icon: "\uf001", Color: 241}, //
".ogv": {Icon: "\uf03d", Color: 241}, //
+ ".opus": {Icon: "\U000f0223", Color: 208}, //
+ ".org": {Icon: "\ue633", Color: 73}, //
".otf": {Icon: "\uf031", Color: 241}, //
+ ".out": {Icon: "\ueae8", Color: 124}, //
".part": {Icon: "\uf43a", Color: 241}, //
".patch": {Icon: "\uf440", Color: 241}, //
".pdf": {Icon: "\uf1c1", Color: 124}, //
".php": {Icon: "\ue73d", Color: 61}, //
".pl": {Icon: "\ue769", Color: 74}, //
+ ".pls": {Icon: "\U000f0cb9", Color: 211}, //
+ ".ply": {Icon: "\U000f01a7", Color: 102}, //
".png": {Icon: "\uf1c5", Color: 241}, //
+ ".po": {Icon: "\U000f05ca", Color: 31}, //
+ ".pot": {Icon: "\U000f05ca", Color: 31}, //
".ppt": {Icon: "\uf1c4", Color: 241}, //
".pptx": {Icon: "\uf1c4", Color: 241}, //
".procfile": {Icon: "\ue21e", Color: 241}, //
@@ -259,6 +343,10 @@ var extIconMap = map[string]IconProperties{
".pxm": {Icon: "\uf1c5", Color: 241}, //
".py": {Icon: "\ue606", Color: 214}, //
".pyc": {Icon: "\ue606", Color: 214}, //
+ ".qm": {Icon: "\U000f05ca", Color: 31}, //
+ ".qml": {Icon: "\uf375", Color: 77}, //
+ ".qrc": {Icon: "\uf375", Color: 77}, //
+ ".qss": {Icon: "\uf375", Color: 77}, //
".r": {Icon: "\uf25d", Color: 68}, //
".rakefile": {Icon: "\ue21e", Color: 160}, //
".rar": {Icon: "\uf410", Color: 241}, //
@@ -281,18 +369,33 @@ var extIconMap = map[string]IconProperties{
".ru": {Icon: "\ue21e", Color: 160}, //
".rubydoc": {Icon: "\ue73b", Color: 160}, //
".sass": {Icon: "\ue603", Color: 169}, //
+ ".scad": {Icon: "\uf34e", Color: 220}, //
".scala": {Icon: "\ue737", Color: 74}, //
".scss": {Icon: "\ue749", Color: 204}, //
".sh": {Icon: "\ue795", Color: 239}, //
".shell": {Icon: "\ue795", Color: 239}, //
+ ".skp": {Icon: "\U000f0eeb", Color: 101}, //
+ ".sldasm": {Icon: "\U000f0eeb", Color: 101}, //
+ ".sldprt": {Icon: "\U000f0eeb", Color: 101}, //
".slim": {Icon: "\ue73b", Color: 160}, //
+ ".slvs": {Icon: "\U000f0eeb", Color: 101}, //
".sln": {Icon: "\ue70c", Color: 39}, //
".so": {Icon: "\uf17c", Color: 241}, //
".sql": {Icon: "\uf1c0", Color: 188}, //
+ ".sqlite": {Icon: "\ue7c4", Color: 25}, //
".sqlite3": {Icon: "\ue7c4", Color: 25}, //
- ".sty": {Icon: "\uf034", Color: 239}, //
+ ".srt": {Icon: "\U000f0a16", Color: 214}, //
+ ".ssa": {Icon: "\U000f0a16", Color: 214}, //
+ ".ste": {Icon: "\U000f0eeb", Color: 101}, //
+ ".step": {Icon: "\U000f0eeb", Color: 101}, //
+ ".stl": {Icon: "\U000f01a7", Color: 102}, //
+ ".sty": {Icon: "\ue69b", Color: 239}, //
".styl": {Icon: "\ue600", Color: 148}, //
".stylus": {Icon: "\ue600", Color: 148}, //
+ ".stp": {Icon: "\U000f0eeb", Color: 101}, //
+ ".sub": {Icon: "\U000f0a16", Color: 214}, //
+ ".sv": {Icon: "\U000f035b", Color: 28}, //
+ ".svh": {Icon: "\U000f035b", Color: 28}, //
".svelte": {Icon: "\ue697", Color: 208}, //
".svg": {Icon: "\uf1c5", Color: 241}, //
".swift": {Icon: "\ue755", Color: 208}, //
@@ -300,12 +403,14 @@ var extIconMap = map[string]IconProperties{
".taz": {Icon: "\uf410", Color: 241}, //
".tbz": {Icon: "\uf410", Color: 241}, //
".tbz2": {Icon: "\uf410", Color: 241}, //
- ".tex": {Icon: "\uf034", Color: 79}, //
+ ".tex": {Icon: "\ue69b", Color: 79}, //
".tgz": {Icon: "\uf410", Color: 241}, //
".tiff": {Icon: "\uf1c5", Color: 241}, //
".tlz": {Icon: "\uf410", Color: 241}, //
".toml": {Icon: "\ue615", Color: 241}, //
".torrent": {Icon: "\ue275", Color: 76}, //
+ ".tres": {Icon: "\ue65f", Color: 66}, //
+ ".tscn": {Icon: "\ue65f", Color: 66}, //
".ts": {Icon: "\ue628", Color: 74}, //
".tsv": {Icon: "\uf1c3", Color: 241}, //
".tsx": {Icon: "\ue7ba", Color: 74}, //
@@ -315,8 +420,14 @@ var extIconMap = map[string]IconProperties{
".txz": {Icon: "\uf410", Color: 241}, //
".tz": {Icon: "\uf410", Color: 241}, //
".tzo": {Icon: "\uf410", Color: 241}, //
+ ".ui": {Icon: "\uf2d0", Color: 17}, //
+ ".v": {Icon: "\U000f035b", Color: 28}, //
+ ".vh": {Icon: "\U000f035b", Color: 28}, //
+ ".vhd": {Icon: "\U000f035b", Color: 28}, //
+ ".vhdl": {Icon: "\U000f035b", Color: 28}, //
".video": {Icon: "\uf03d", Color: 241}, //
".vim": {Icon: "\ue62b", Color: 28}, //
+ ".vsix": {Icon: "\ue70c", Color: 98}, //
".vue": {Icon: "\U000f0844", Color: 113}, //
".war": {Icon: "\ue256", Color: 168}, //
".wav": {Icon: "\uf001", Color: 241}, //
@@ -325,14 +436,19 @@ var extIconMap = map[string]IconProperties{
".windows": {Icon: "\uf17a", Color: 81}, //
".woff": {Icon: "\uf031", Color: 241}, //
".woff2": {Icon: "\uf031", Color: 241}, //
+ ".wrl": {Icon: "\U000f01a7", Color: 102}, //
+ ".wrz": {Icon: "\U000f01a7", Color: 102}, //
+ ".xcf": {Icon: "\uf338", Color: 240}, //
".xhtml": {Icon: "\uf13b", Color: 196}, //
".xls": {Icon: "\uf1c3", Color: 34}, //
".xlsx": {Icon: "\uf1c3", Color: 34}, //
".xml": {Icon: "\uf121", Color: 160}, //
+ ".xpi": {Icon: "\ueae6", Color: 17}, //
".xul": {Icon: "\uf121", Color: 166}, //
".xz": {Icon: "\uf410", Color: 241}, //
".yaml": {Icon: "\uf481", Color: 160}, //
".yml": {Icon: "\uf481", Color: 160}, //
+ ".zig": {Icon: "\ue6a9", Color: 172}, //
".zip": {Icon: "\uf410", Color: 241}, //
".zsh": {Icon: "\ue795", Color: 241}, //
".zsh-theme": {Icon: "\ue795", Color: 241}, //
From 1129e0e4a08648f2c2db4cde550b296fcf8cda2d Mon Sep 17 00:00:00 2001
From: hasecilu
Date: Sun, 7 Apr 2024 17:46:13 -0600
Subject: [PATCH 19/36] Add icons for some git remotes
---
pkg/gui/presentation/icons/git_icons.go | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/pkg/gui/presentation/icons/git_icons.go b/pkg/gui/presentation/icons/git_icons.go
index 5a7c0afc6..55ada2e51 100644
--- a/pkg/gui/presentation/icons/git_icons.go
+++ b/pkg/gui/presentation/icons/git_icons.go
@@ -19,10 +19,20 @@ var (
)
var remoteIcons = map[string]string{
- "github.com": "\ue709", //
- "bitbucket.org": "\ue703", //
- "gitlab.com": "\uf296", //
- "dev.azure.com": "\U000f0805", //
+ "github.com": "\ue709", //
+ "bitbucket.org": "\ue703", //
+ "gitlab.com": "\uf296", //
+ "dev.azure.com": "\U000f0805", //
+ "codeberg.org": "\uf330", //
+ "git.FreeBSD.org": "\uf30c", //
+ "gitlab.archlinux.org": "\uf303", //
+ "gitlab.freedesktop.org": "\uf360", //
+ "gitlab.gnome.org": "\uf361", //
+ "gnu.org": "\ue779", //
+ "invent.kde.org": "\uf373", //
+ "kernel.org": "\uf31a", //
+ "salsa.debian.org": "\uf306", //
+ "sr.ht": "\uf1db", //
}
func patchGitIconsForNerdFontsV2() {
From c5de9cfd8e869e993fd1e795936da49cdded38d8 Mon Sep 17 00:00:00 2001
From: hasecilu
Date: Mon, 8 Jul 2024 11:03:28 -0600
Subject: [PATCH 20/36] fixup! Add icons for some file extensions
---
pkg/gui/presentation/icons/file_icons.go | 228 ++++++++++++++++++-----
1 file changed, 186 insertions(+), 42 deletions(-)
diff --git a/pkg/gui/presentation/icons/file_icons.go b/pkg/gui/presentation/icons/file_icons.go
index e98bb3961..f0fcb69e6 100644
--- a/pkg/gui/presentation/icons/file_icons.go
+++ b/pkg/gui/presentation/icons/file_icons.go
@@ -82,94 +82,132 @@ var nameIconMap = map[string]IconProperties{
var extIconMap = map[string]IconProperties{
".3gp": {Icon: "\uf03d", Color: 208}, //
".3mf": {Icon: "\U000f01a7", Color: 102}, //
+ ".7z": {Icon: "\uf410", Color: 214}, //
".aac": {Icon: "\uf001", Color: 45}, //
+ ".a": {Icon: "\ueb9c", Color: 253}, //
+ ".aiff": {Icon: "\uf001", Color: 39}, //
+ ".aif": {Icon: "\uf001", Color: 39}, //
".ai": {Icon: "\ue7b4", Color: 185}, //
".android": {Icon: "\ue70e", Color: 70}, //
+ ".ape": {Icon: "\uf001", Color: 39}, //
".apk": {Icon: "\ue70e", Color: 70}, //
".app": {Icon: "\ueae8", Color: 124}, //
".apple": {Icon: "\uf179", Color: 15}, //
".applescript": {Icon: "\uf179", Color: 66}, //
+ ".asc": {Icon: "\uf099d", Color: 242}, //
".ass": {Icon: "\U000f0a16", Color: 214}, //
- ".avi": {Icon: "\uf03d", Color: 140}, //
+ ".astro": {Icon: "\ue6b3", Color: 197}, //
".avif": {Icon: "\uf1c5", Color: 140}, //
+ ".avi": {Icon: "\uf03d", Color: 140}, //
".avro": {Icon: "\ue60b", Color: 130}, //
".awk": {Icon: "\ue795", Color: 140}, //
".azcli": {Icon: "\uebe8", Color: 32}, //
".bak": {Icon: "\U000f006f", Color: 66}, //
- ".bash": {Icon: "\ue795", Color: 113}, //
".bash_history": {Icon: "\ue795", Color: 113}, //
+ ".bash": {Icon: "\ue795", Color: 113}, //
".bash_profile": {Icon: "\ue795", Color: 113}, //
".bashrc": {Icon: "\ue795", Color: 113}, //
".bat": {Icon: "\uf17a", Color: 81}, //
".bats": {Icon: "\ue795", Color: 241}, //
".bazel": {Icon: "\ue63a", Color: 113}, //
".bib": {Icon: "\U000f125f", Color: 185}, //
+ ".bicep": {Icon: "\ue63b", Color: 32}, //
+ ".bicepparam": {Icon: "\ue63b", Color: 103}, //
+ ".blade.php": {Icon: "\uf2f7", Color: 203}, //
".blend": {Icon: "\U000f00ab", Color: 208}, //
".blp": {Icon: "\U000f0ebe", Color: 68}, //
".bmp": {Icon: "\uf1c5", Color: 149}, //
".brep": {Icon: "\U000f0eeb", Color: 101}, //
- ".bz": {Icon: "\uf410", Color: 239}, //
".bz2": {Icon: "\uf410", Color: 239}, //
+ ".bz3": {Icon: "\uf410", Color: 214}, //
+ ".bz": {Icon: "\uf410", Color: 239}, //
".bzl": {Icon: "\ue63a", Color: 113}, //
- ".c": {Icon: "\ue61e", Color: 111}, //
- ".c++": {Icon: "\ue61d", Color: 204}, //
".cab": {Icon: "\ue70f", Color: 241}, //
".cache": {Icon: "\uf49b", Color: 231}, //
".cast": {Icon: "\uf03d", Color: 208}, //
+ ".cbl": {Icon: "\u2699", Color: 25}, // ⚙
".cc": {Icon: "\ue61d", Color: 204}, //
+ ".ccm": {Icon: "\ue61d", Color: 204}, //
".cfg": {Icon: "\ue615", Color: 255}, //
+ ".c++": {Icon: "\ue61d", Color: 204}, //
+ ".c": {Icon: "\ue61e", Color: 111}, //
+ ".cjs": {Icon: "\ue60c", Color: 185}, //
".class": {Icon: "\ue256", Color: 168}, //
+ ".cljc": {Icon: "\ue768", Color: 113}, //
+ ".cljd": {Icon: "\ue76a", Color: 74}, //
".clj": {Icon: "\ue768", Color: 113}, //
".cljs": {Icon: "\ue76a", Color: 74}, //
".cls": {Icon: "\ue69b", Color: 239}, //
+ ".cmake": {Icon: "\ue615", Color: 66}, //
".cmd": {Icon: "\ue70f", Color: 239}, //
+ ".cob": {Icon: "\u2699", Color: 25}, // ⚙
+ ".cobol": {Icon: "\u2699", Color: 25}, // ⚙
".coffee": {Icon: "\uf0f4", Color: 185}, //
".conf": {Icon: "\ue615", Color: 66}, //
+ ".config.ru": {Icon: "\ue791", Color: 52}, //
".cp": {Icon: "\ue61d", Color: 74}, //
".cpio": {Icon: "\uf410", Color: 239}, //
".cpp": {Icon: "\ue61d", Color: 74}, //
- ".cs": {Icon: "\U000f031b", Color: 58}, //
+ ".cppm": {Icon: "\ue61d", Color: 74}, //
+ ".cpy": {Icon: "\u2699", Color: 25}, // ⚙
+ ".crdownload": {Icon: "\uf019", Color: 43}, //
+ ".cr": {Icon: "\ue62f", Color: 251}, //
".csh": {Icon: "\ue795", Color: 240}, //
".cshtml": {Icon: "\uf1fa", Color: 239}, //
+ ".cs": {Icon: "\U000f031b", Color: 58}, //
+ ".cson": {Icon: "\ue60b", Color: 185}, //
".csproj": {Icon: "\U000f031b", Color: 58}, //
".css": {Icon: "\ue749", Color: 75}, //
".csv": {Icon: "\uf1c3", Color: 113}, //
".csx": {Icon: "\U000f031b", Color: 58}, //
+ ".cts": {Icon: "\ue628", Color: 74}, //
".cue": {Icon: "\U000f0cb9", Color: 211}, //
+ ".cuh": {Icon: "\ue64b", Color: 140}, //
+ ".cu": {Icon: "\ue64b", Color: 113}, //
".cxx": {Icon: "\ue61d", Color: 74}, //
- ".bicep": {Icon: "\ue63b", Color: 32}, //
- ".bicepparam": {Icon: "\ue63b", Color: 103}, //
- ".d": {Icon: "\ue7af", Color: 28}, //
+ ".cxxm": {Icon: "\ue61d", Color: 74}, //
".dart": {Icon: "\ue798", Color: 25}, //
- ".dconf": {Icon: "\ue706", Color: 188}, //
".db": {Icon: "\uf1c0", Color: 188}, //
+ ".dconf": {Icon: "\ue706", Color: 188}, //
".deb": {Icon: "\ue77d", Color: 88}, //
".desktop": {Icon: "\uf108", Color: 54}, //
+ ".d": {Icon: "\ue7af", Color: 28}, //
".diff": {Icon: "\uf440", Color: 241}, //
".djvu": {Icon: "\uf02d", Color: 241}, //
".dll": {Icon: "\ue70f", Color: 241}, //
".doc": {Icon: "\U000f0219", Color: 26}, //
".docx": {Icon: "\U000f0219", Color: 26}, //
".dot": {Icon: "\U000f1049", Color: 24}, //
+ ".download": {Icon: "\uf019", Color: 43}, //
+ ".drl": {Icon: "\ue28c", Color: 217}, //
+ ".dropbox": {Icon: "\ue707", Color: 27}, //
".ds_store": {Icon: "\uf179", Color: 15}, //
".DS_store": {Icon: "\uf179", Color: 15}, //
+ ".d.ts": {Icon: "\ue628", Color: 172}, //
".dump": {Icon: "\uf1c0", Color: 188}, //
".dwg": {Icon: "\U000f0eeb", Color: 101}, //
".dxf": {Icon: "\U000f0eeb", Color: 101}, //
".ebook": {Icon: "\ue28b", Color: 241}, //
".ebuild": {Icon: "\uf30d", Color: 56}, //
".editorconfig": {Icon: "\ue615", Color: 241}, //
+ ".edn": {Icon: "\ue76a", Color: 74}, //
+ ".eex": {Icon: "\ue62d", Color: 140}, //
".ejs": {Icon: "\ue618", Color: 185}, //
+ ".elc": {Icon: "\ue632", Color: 97}, //
".elf": {Icon: "\ueae8", Color: 124}, //
+ ".el": {Icon: "\ue632", Color: 97}, //
".elm": {Icon: "\ue62c", Color: 74}, //
+ ".eln": {Icon: "\ue632", Color: 97}, //
".env": {Icon: "\uf462", Color: 227}, //
".eot": {Icon: "\uf031", Color: 124}, //
+ ".epp": {Icon: "\ue631", Color: 214}, //
".epub": {Icon: "\ue28a", Color: 241}, //
".erb": {Icon: "\ue73b", Color: 160}, //
".erl": {Icon: "\ue7b1", Color: 163}, //
- ".ex": {Icon: "\ue62d", Color: 140}, //
".exe": {Icon: "\uf17a", Color: 81}, //
+ ".ex": {Icon: "\ue62d", Color: 140}, //
".exs": {Icon: "\ue62d", Color: 140}, //
+ ".f3d": {Icon: "\uf0eeb", Color: 101}, //
".f90": {Icon: "\U000f121a", Color: 97}, //
".fbx": {Icon: "\U000f01a7", Color: 102}, //
".fcbak": {Icon: "\uf336", Color: 160}, //
@@ -177,10 +215,12 @@ var extIconMap = map[string]IconProperties{
".fcmat": {Icon: "\uf336", Color: 160}, //
".fcparam": {Icon: "\uf336", Color: 160}, //
".fcscript": {Icon: "\uf336", Color: 160}, //
- ".fcstd": {Icon: "\uf336", Color: 160}, //
".fcstd1": {Icon: "\uf336", Color: 160}, //
+ ".fcstd": {Icon: "\uf336", Color: 160}, //
".fctb": {Icon: "\uf336", Color: 160}, //
".fctl": {Icon: "\uf336", Color: 160}, //
+ ".fdmdownload": {Icon: "\uf019", Color: 43}, //
+ ".f#": {Icon: "\ue7a7", Color: 74}, //
".fish": {Icon: "\ue795", Color: 249}, //
".flac": {Icon: "\uf001", Color: 241}, //
".flc": {Icon: "\uf031", Color: 255}, //
@@ -190,24 +230,24 @@ var extIconMap = map[string]IconProperties{
".font": {Icon: "\uf031", Color: 241}, //
".fs": {Icon: "\ue7a7", Color: 74}, //
".fsi": {Icon: "\ue7a7", Color: 74}, //
+ ".fsscript": {Icon: "\ue7a7", Color: 74}, //
".fsx": {Icon: "\ue7a7", Color: 74}, //
".gcode": {Icon: "\U000f0af4", Color: 234}, //
".gd": {Icon: "\ue65f", Color: 66}, //
".gdoc": {Icon: "\uf1c2", Color: 40}, //
- ".gem": {Icon: "\ue21e", Color: 160}, //
".gemfile": {Icon: "\ue21e", Color: 160}, //
+ ".gem": {Icon: "\ue21e", Color: 160}, //
".gemspec": {Icon: "\ue21e", Color: 160}, //
".gform": {Icon: "\uf298", Color: 40}, //
".gif": {Icon: "\uf1c5", Color: 140}, //
- ".git": {Icon: "\uf1d3", Color: 202}, //
- ".gitattributes": {Icon: "\uf1d3", Color: 202}, //
- ".gitignore": {Icon: "\uf1d3", Color: 202}, //
- ".gitmodules": {Icon: "\uf1d3", Color: 202}, //
- ".go": {Icon: "\ue627", Color: 74}, //
+ ".git": {Icon: "\U000f02a2", Color: 202}, //
+ ".glb": {Icon: "\uf1b2", Color: 214}, //
+ ".gnumakefile": {Icon: "\ue779", Color: 66}, //
".godot": {Icon: "\ue65f", Color: 66}, //
+ ".go": {Icon: "\ue627", Color: 74}, //
".gql": {Icon: "\uf20e", Color: 199}, //
- ".graphql": {Icon: "\uf20e", Color: 199}, //
".gradle": {Icon: "\ue256", Color: 168}, //
+ ".graphql": {Icon: "\uf20e", Color: 199}, //
".gresource": {Icon: "\uf362", Color: 231}, //
".groovy": {Icon: "\ue775", Color: 24}, //
".gsheet": {Icon: "\uf1c3", Color: 10}, //
@@ -215,47 +255,66 @@ var extIconMap = map[string]IconProperties{
".guardfile": {Icon: "\ue21e", Color: 241}, //
".gv": {Icon: "\U000f1049", Color: 24}, //
".gz": {Icon: "\uf410", Color: 241}, //
- ".h": {Icon: "\uf0fd", Color: 140}, //
+ ".haml": {Icon: "\ue60e", Color: 255}, //
".hbs": {Icon: "\ue60f", Color: 202}, //
".hc": {Icon: "\U000f00a2", Color: 227}, //
+ ".heex": {Icon: "\ue62d", Color: 140}, //
".hex": {Icon: "\U000f12a7", Color: 27}, //
".hh": {Icon: "\uf0fd", Color: 140}, //
+ ".h": {Icon: "\uf0fd", Color: 140}, //
".hpp": {Icon: "\uf0fd", Color: 140}, //
+ ".hrl": {Icon: "\ue7b1", Color: 163}, //
".hs": {Icon: "\ue777", Color: 140}, //
".htm": {Icon: "\uf13b", Color: 196}, //
".html": {Icon: "\uf13b", Color: 196}, //
+ ".huff": {Icon: "\uf0858", Color: 56}, //
+ ".hurl": {Icon: "\uf0ec", Color: 198}, //
+ ".hx": {Icon: "\ue666", Color: 208}, //
".hxx": {Icon: "\uf0fd", Color: 140}, //
+ ".icalendar": {Icon: "\uf073", Color: 18}, //
+ ".ical": {Icon: "\uf073", Color: 18}, //
".ico": {Icon: "\uf1c5", Color: 185}, //
+ ".ics": {Icon: "\uf073", Color: 18}, //
+ ".ifb": {Icon: "\uf073", Color: 18}, //
".ifc": {Icon: "\U000f0eeb", Color: 101}, //
".ige": {Icon: "\U000f0eeb", Color: 101}, //
".iges": {Icon: "\U000f0eeb", Color: 101}, //
".igs": {Icon: "\U000f0eeb", Color: 101}, //
".image": {Icon: "\uf1c5", Color: 185}, //
+ ".img": {Icon: "\ue271", Color: 181}, //
".iml": {Icon: "\ue7b5", Color: 239}, //
+ ".import": {Icon: "\uf0c6", Color: 255}, //
".info": {Icon: "\uf129", Color: 230}, //
".ini": {Icon: "\uf17a", Color: 81}, //
".ino": {Icon: "\uf34b", Color: 73}, //
".ipynb": {Icon: "\ue606", Color: 214}, //
".iso": {Icon: "\ue271", Color: 239}, //
+ ".ixx": {Icon: "\ue61d", Color: 74}, //
".j2c": {Icon: "\uf1c5", Color: 239}, //
".j2k": {Icon: "\uf1c5", Color: 239}, //
".jad": {Icon: "\ue256", Color: 168}, //
".jar": {Icon: "\ue256", Color: 168}, //
".java": {Icon: "\ue256", Color: 168}, //
- ".jfi": {Icon: "\uf1c5", Color: 241}, //
".jfif": {Icon: "\uf1c5", Color: 241}, //
+ ".jfi": {Icon: "\uf1c5", Color: 241}, //
".jif": {Icon: "\uf1c5", Color: 241}, //
".jl": {Icon: "\ue624", Color: 241}, //
".jmd": {Icon: "\uf48a", Color: 74}, //
".jp2": {Icon: "\uf1c5", Color: 241}, //
- ".jpe": {Icon: "\uf1c5", Color: 241}, //
".jpeg": {Icon: "\uf1c5", Color: 241}, //
+ ".jpe": {Icon: "\uf1c5", Color: 241}, //
".jpg": {Icon: "\uf1c5", Color: 241}, //
".jpx": {Icon: "\uf1c5", Color: 241}, //
".js": {Icon: "\ue74e", Color: 185}, //
+ ".json5": {Icon: "\ue60b", Color: 185}, //
+ ".jsonc": {Icon: "\ue60b", Color: 185}, //
".json": {Icon: "\ue60b", Color: 185}, //
".jsx": {Icon: "\ue7ba", Color: 45}, //
+ ".jwmrc": {Icon: "\uf35b", Color: 32}, //
".jxl": {Icon: "\uf1c5", Color: 241}, //
+ ".kbx": {Icon: "\uf0bc4", Color: 243}, //
+ ".kdb": {Icon: "\uf23e", Color: 71}, //
+ ".kdbx": {Icon: "\uf23e", Color: 71}, //
".kdenlive": {Icon: "\uf33c", Color: 110}, //
".kdenlivetitle": {Icon: "\uf33c", Color: 110}, //
".kicad_dru": {Icon: "\uf34c", Color: 231}, //
@@ -266,6 +325,7 @@ var extIconMap = map[string]IconProperties{
".kicad_sch": {Icon: "\uf34c", Color: 231}, //
".kicad_sym": {Icon: "\uf34c", Color: 231}, //
".kicad_wks": {Icon: "\uf34c", Color: 231}, //
+ ".ko": {Icon: "\uf17c", Color: 253}, //
".kpp": {Icon: "\uf33d", Color: 201}, //
".kra": {Icon: "\uf33d", Color: 201}, //
".krz": {Icon: "\uf33d", Color: 201}, //
@@ -274,81 +334,115 @@ var extIconMap = map[string]IconProperties{
".kts": {Icon: "\ue634", Color: 99}, //
".latex": {Icon: "\ue69b", Color: 241}, //
".lck": {Icon: "\ue672", Color: 250}, //
+ ".leex": {Icon: "\ue62d", Color: 140}, //
".less": {Icon: "\ue758", Color: 54}, //
+ ".lff": {Icon: "\uf031", Color: 255}, //
".lhs": {Icon: "\ue777", Color: 140}, //
".license": {Icon: "\U000f0219", Color: 185}, //
+ ".liquid": {Icon: "\ue670", Color: 106}, //
".localized": {Icon: "\uf179", Color: 15}, //
".lock": {Icon: "\uf023", Color: 241}, //
".log": {Icon: "\uf4ed", Color: 188}, //
".lrc": {Icon: "\U000f0a16", Color: 214}, //
- ".lua": {Icon: "\ue620", Color: 74}, //
".luac": {Icon: "\ue620", Color: 74}, //
+ ".lua": {Icon: "\ue620", Color: 74}, //
".luau": {Icon: "\ue620", Color: 74}, //
- ".lz": {Icon: "\uf410", Color: 241}, //
".lz4": {Icon: "\uf410", Color: 241}, //
".lzh": {Icon: "\uf410", Color: 241}, //
+ ".lz": {Icon: "\uf410", Color: 241}, //
".lzma": {Icon: "\uf410", Color: 241}, //
".lzo": {Icon: "\uf410", Color: 241}, //
- ".m": {Icon: "\ue61e", Color: 111}, //
- ".m3u": {Icon: "\U000f0cb9", Color: 211}, //
".m3u8": {Icon: "\U000f0cb9", Color: 211}, //
+ ".m3u": {Icon: "\U000f0cb9", Color: 211}, //
".m4a": {Icon: "\uf001", Color: 239}, //
".m4v": {Icon: "\uf03d", Color: 208}, //
".magnet": {Icon: "\uf076", Color: 124}, //
".makefile": {Icon: "\ue779", Color: 66}, //
".markdown": {Icon: "\uf48a", Color: 74}, //
+ ".material": {Icon: "\uf0509", Color: 163}, //
+ ".md5": {Icon: "\uf0565", Color: 103}, //
".md": {Icon: "\uf48a", Color: 74}, //
".mdx": {Icon: "\uf48a", Color: 74}, //
+ ".m": {Icon: "\ue61e", Color: 111}, //
+ ".mint": {Icon: "\uf032a", Color: 108}, //
".mjs": {Icon: "\ue74e", Color: 185}, //
- ".mk": {Icon: "\ue795", Color: 241}, //
".mkd": {Icon: "\uf48a", Color: 74}, //
+ ".mk": {Icon: "\ue795", Color: 241}, //
".mkv": {Icon: "\uf03d", Color: 241}, //
+ ".ml": {Icon: "\ue67a", Color: 166}, //
+ ".mli": {Icon: "\ue67a", Color: 166}, //
".mm": {Icon: "\ue61d", Color: 111}, //
".mobi": {Icon: "\ue28b", Color: 241}, //
+ ".mo": {Icon: "\u221e", Color: 135}, // ∞
+ ".mojo": {Icon: "\uf06d", Color: 196}, //
".mov": {Icon: "\uf03d", Color: 241}, //
".mp3": {Icon: "\uf001", Color: 241}, //
".mp4": {Icon: "\uf03d", Color: 241}, //
+ ".mpp": {Icon: "\ue61d", Color: 74}, //
+ ".msf": {Icon: "\uf370", Color: 33}, //
".msi": {Icon: "\ue70f", Color: 241}, //
+ ".mts": {Icon: "\ue628", Color: 74}, //
".mustache": {Icon: "\ue60f", Color: 241}, //
".nfo": {Icon: "\uf129", Color: 230}, //
+ ".nim": {Icon: "\ue677", Color: 220}, //
".nix": {Icon: "\uf313", Color: 111}, //
".node": {Icon: "\U000f0399", Color: 197}, //
".npmignore": {Icon: "\ue71e", Color: 197}, //
+ ".nswag": {Icon: "\ue60b", Color: 112}, //
+ ".nu": {Icon: "\u003e", Color: 36}, // >
".obj": {Icon: "\U000f01a7", Color: 102}, //
".odp": {Icon: "\uf1c4", Color: 241}, //
".ods": {Icon: "\uf1c3", Color: 241}, //
".odt": {Icon: "\uf1c2", Color: 241}, //
".ogg": {Icon: "\uf001", Color: 241}, //
".ogv": {Icon: "\uf03d", Color: 241}, //
+ ".o": {Icon: "\ueae8", Color: 124}, //
".opus": {Icon: "\U000f0223", Color: 208}, //
".org": {Icon: "\ue633", Color: 73}, //
".otf": {Icon: "\uf031", Color: 241}, //
".out": {Icon: "\ueae8", Color: 124}, //
".part": {Icon: "\uf43a", Color: 241}, //
".patch": {Icon: "\uf440", Color: 241}, //
+ ".pck": {Icon: "\uf487", Color: 66}, //
".pdf": {Icon: "\uf1c1", Color: 124}, //
".php": {Icon: "\ue73d", Color: 61}, //
".pl": {Icon: "\ue769", Color: 74}, //
".pls": {Icon: "\U000f0cb9", Color: 211}, //
".ply": {Icon: "\U000f01a7", Color: 102}, //
+ ".pm": {Icon: "\ue769", Color: 74}, //
".png": {Icon: "\uf1c5", Color: 241}, //
".po": {Icon: "\U000f05ca", Color: 31}, //
".pot": {Icon: "\U000f05ca", Color: 31}, //
+ ".pp": {Icon: "\ue631", Color: 214}, //
".ppt": {Icon: "\uf1c4", Color: 241}, //
".pptx": {Icon: "\uf1c4", Color: 241}, //
+ ".prisma": {Icon: "\ue684", Color: 62}, //
".procfile": {Icon: "\ue21e", Color: 241}, //
+ ".pro": {Icon: "\ue7a1", Color: 179}, //
".properties": {Icon: "\ue60b", Color: 185}, //
".ps1": {Icon: "\ue795", Color: 241}, //
+ ".psb": {Icon: "\ue7b8", Color: 74}, //
+ ".psd1": {Icon: "\uf0a0a", Color: 68}, //
".psd": {Icon: "\ue7b8", Color: 241}, //
+ ".psm1": {Icon: "\uf0a0a", Color: 68}, //
+ ".pub": {Icon: "\uf0dd6", Color: 222}, //
+ ".pxd": {Icon: "\ue606", Color: 39}, //
+ ".pxi": {Icon: "\ue606", Color: 39}, //
".pxm": {Icon: "\uf1c5", Color: 241}, //
- ".py": {Icon: "\ue606", Color: 214}, //
".pyc": {Icon: "\ue606", Color: 214}, //
+ ".pyd": {Icon: "\ue606", Color: 222}, //
+ ".py": {Icon: "\ue606", Color: 214}, //
+ ".pyi": {Icon: "\ue606", Color: 214}, //
+ ".pyo": {Icon: "\ue606", Color: 222}, //
+ ".pyw": {Icon: "\ue606", Color: 39}, //
+ ".pyx": {Icon: "\ue606", Color: 39}, //
".qm": {Icon: "\U000f05ca", Color: 31}, //
".qml": {Icon: "\uf375", Color: 77}, //
".qrc": {Icon: "\uf375", Color: 77}, //
".qss": {Icon: "\uf375", Color: 77}, //
- ".r": {Icon: "\uf25d", Color: 68}, //
+ ".query": {Icon: "\ue21c", Color: 107}, //
".rakefile": {Icon: "\ue21e", Color: 160}, //
+ ".rake": {Icon: "\ue791", Color: 52}, //
".rar": {Icon: "\uf410", Color: 241}, //
".razor": {Icon: "\uf1fa", Color: 81}, //
".rb": {Icon: "\ue21e", Color: 160}, //
@@ -357,60 +451,96 @@ var extIconMap = map[string]IconProperties{
".rdoc": {Icon: "\uf48a", Color: 74}, //
".rds": {Icon: "\uf25d", Color: 68}, //
".readme": {Icon: "\uf48a", Color: 74}, //
+ ".res": {Icon: "\ue688", Color: 167}, //
+ ".resi": {Icon: "\ue688", Color: 204}, //
+ ".r": {Icon: "\uf25d", Color: 68}, //
".rlib": {Icon: "\ue7a8", Color: 216}, //
".rmd": {Icon: "\uf48a", Color: 74}, //
".rpm": {Icon: "\ue7bb", Color: 52}, //
+ ".rproj": {Icon: "\uf05c6", Color: 29}, //
".rs": {Icon: "\ue7a8", Color: 216}, //
".rspec": {Icon: "\ue21e", Color: 160}, //
".rspec_parallel": {Icon: "\ue21e", Color: 160}, //
".rspec_status": {Icon: "\ue21e", Color: 160}, //
".rss": {Icon: "\uf09e", Color: 130}, //
".rtf": {Icon: "\U000f0219", Color: 241}, //
- ".ru": {Icon: "\ue21e", Color: 160}, //
".rubydoc": {Icon: "\ue73b", Color: 160}, //
+ ".ru": {Icon: "\ue21e", Color: 160}, //
".sass": {Icon: "\ue603", Color: 169}, //
+ ".sbt": {Icon: "\ue737", Color: 167}, //
".scad": {Icon: "\uf34e", Color: 220}, //
".scala": {Icon: "\ue737", Color: 74}, //
+ ".sc": {Icon: "\ue737", Color: 167}, //
+ ".scm": {Icon: "\uf0627", Color: 255}, //
".scss": {Icon: "\ue749", Color: 204}, //
- ".sh": {Icon: "\ue795", Color: 239}, //
+ ".sha1": {Icon: "\uf0565", Color: 103}, //
+ ".sha224": {Icon: "\uf0565", Color: 103}, //
+ ".sha256": {Icon: "\uf0565", Color: 103}, //
+ ".sha384": {Icon: "\uf0565", Color: 103}, //
+ ".sha512": {Icon: "\uf0565", Color: 103}, //
".shell": {Icon: "\ue795", Color: 239}, //
+ ".sh": {Icon: "\ue795", Color: 239}, //
+ ".sig": {Icon: "\u03bb", Color: 166}, // λ
+ ".signature": {Icon: "\u03bb", Color: 166}, // λ
".skp": {Icon: "\U000f0eeb", Color: 101}, //
".sldasm": {Icon: "\U000f0eeb", Color: 101}, //
".sldprt": {Icon: "\U000f0eeb", Color: 101}, //
".slim": {Icon: "\ue73b", Color: 160}, //
- ".slvs": {Icon: "\U000f0eeb", Color: 101}, //
".sln": {Icon: "\ue70c", Color: 39}, //
+ ".slvs": {Icon: "\U000f0eeb", Color: 101}, //
+ ".sml": {Icon: "\u03bb", Color: 166}, // λ
".so": {Icon: "\uf17c", Color: 241}, //
+ ".sol": {Icon: "\ue656", Color: 74}, //
+ ".spec.js": {Icon: "\uf499", Color: 185}, //
+ ".spec.jsx": {Icon: "\uf499", Color: 45}, //
+ ".spec.ts": {Icon: "\uf499", Color: 74}, //
+ ".spec.tsx": {Icon: "\uf499", Color: 26}, //
".sql": {Icon: "\uf1c0", Color: 188}, //
- ".sqlite": {Icon: "\ue7c4", Color: 25}, //
".sqlite3": {Icon: "\ue7c4", Color: 25}, //
+ ".sqlite": {Icon: "\ue7c4", Color: 25}, //
".srt": {Icon: "\U000f0a16", Color: 214}, //
".ssa": {Icon: "\U000f0a16", Color: 214}, //
".ste": {Icon: "\U000f0eeb", Color: 101}, //
".step": {Icon: "\U000f0eeb", Color: 101}, //
".stl": {Icon: "\U000f01a7", Color: 102}, //
+ ".stp": {Icon: "\U000f0eeb", Color: 101}, //
+ ".strings": {Icon: "\U000f05ca", Color: 31}, //
".sty": {Icon: "\ue69b", Color: 239}, //
".styl": {Icon: "\ue600", Color: 148}, //
".stylus": {Icon: "\ue600", Color: 148}, //
- ".stp": {Icon: "\U000f0eeb", Color: 101}, //
".sub": {Icon: "\U000f0a16", Color: 214}, //
- ".sv": {Icon: "\U000f035b", Color: 28}, //
- ".svh": {Icon: "\U000f035b", Color: 28}, //
+ ".sublime": {Icon: "\ue7aa", Color: 166}, //
+ ".suo": {Icon: "\ue70c", Color: 98}, //
".svelte": {Icon: "\ue697", Color: 208}, //
".svg": {Icon: "\uf1c5", Color: 241}, //
+ ".svh": {Icon: "\U000f035b", Color: 28}, //
+ ".sv": {Icon: "\U000f035b", Color: 28}, //
".swift": {Icon: "\ue755", Color: 208}, //
".tar": {Icon: "\uf410", Color: 241}, //
".taz": {Icon: "\uf410", Color: 241}, //
- ".tbz": {Icon: "\uf410", Color: 241}, //
+ ".tbc": {Icon: "\uf06d3", Color: 25}, //
".tbz2": {Icon: "\uf410", Color: 241}, //
+ ".tbz": {Icon: "\uf410", Color: 241}, //
+ ".tcl": {Icon: "\uf06d3", Color: 25}, //
+ ".templ": {Icon: "\ueac4", Color: 178}, //
+ ".terminal": {Icon: "\uf489", Color: 34}, //
+ ".test.js": {Icon: "\uf499", Color: 185}, //
+ ".test.jsx": {Icon: "\uf499", Color: 45}, //
+ ".test.ts": {Icon: "\uf499", Color: 74}, //
+ ".test.tsx": {Icon: "\uf499", Color: 26}, //
".tex": {Icon: "\ue69b", Color: 79}, //
+ ".tf": {Icon: "\ue69a", Color: 93}, //
+ ".tfvars": {Icon: "\uf15b", Color: 93}, //
".tgz": {Icon: "\uf410", Color: 241}, //
+ ".t": {Icon: "\ue769", Color: 74}, //
".tiff": {Icon: "\uf1c5", Color: 241}, //
".tlz": {Icon: "\uf410", Color: 241}, //
- ".toml": {Icon: "\ue615", Color: 241}, //
+ ".tmux": {Icon: "\uebc8", Color: 34}, //
+ ".toml": {Icon: "\ue6b2", Color: 241}, //
".torrent": {Icon: "\ue275", Color: 76}, //
".tres": {Icon: "\ue65f", Color: 66}, //
".tscn": {Icon: "\ue65f", Color: 66}, //
+ ".tsconfig": {Icon: "\ue772", Color: 208}, //
".ts": {Icon: "\ue628", Color: 74}, //
".tsv": {Icon: "\uf1c3", Color: 241}, //
".tsx": {Icon: "\ue7ba", Color: 74}, //
@@ -418,30 +548,44 @@ var extIconMap = map[string]IconProperties{
".twig": {Icon: "\ue61c", Color: 241}, //
".txt": {Icon: "\uf15c", Color: 241}, //
".txz": {Icon: "\uf410", Color: 241}, //
+ ".typoscript": {Icon: "\ue772", Color: 208}, //
".tz": {Icon: "\uf410", Color: 241}, //
".tzo": {Icon: "\uf410", Color: 241}, //
".ui": {Icon: "\uf2d0", Color: 17}, //
- ".v": {Icon: "\U000f035b", Color: 28}, //
- ".vh": {Icon: "\U000f035b", Color: 28}, //
+ ".vala": {Icon: "\ue69e", Color: 91}, //
".vhd": {Icon: "\U000f035b", Color: 28}, //
".vhdl": {Icon: "\U000f035b", Color: 28}, //
+ ".vh": {Icon: "\U000f035b", Color: 28}, //
+ ".v": {Icon: "\U000f035b", Color: 28}, //
".video": {Icon: "\uf03d", Color: 241}, //
".vim": {Icon: "\ue62b", Color: 28}, //
+ ".vsh": {Icon: "\ue6ac", Color: 67}, //
".vsix": {Icon: "\ue70c", Color: 98}, //
".vue": {Icon: "\U000f0844", Color: 113}, //
".war": {Icon: "\ue256", Color: 168}, //
+ ".wasm": {Icon: "\ue6a1", Color: 62}, //
".wav": {Icon: "\uf001", Color: 241}, //
+ ".webmanifest": {Icon: "\ue60b", Color: 185}, //
".webm": {Icon: "\uf03d", Color: 241}, //
+ ".webpack": {Icon: "\uf072b", Color: 74}, //
".webp": {Icon: "\uf1c5", Color: 241}, //
".windows": {Icon: "\uf17a", Color: 81}, //
- ".woff": {Icon: "\uf031", Color: 241}, //
+ ".wma": {Icon: "\uf001", Color: 39}, //
".woff2": {Icon: "\uf031", Color: 241}, //
+ ".woff": {Icon: "\uf031", Color: 241}, //
".wrl": {Icon: "\U000f01a7", Color: 102}, //
".wrz": {Icon: "\U000f01a7", Color: 102}, //
+ ".wvc": {Icon: "\uf001", Color: 39}, //
+ ".wv": {Icon: "\uf001", Color: 39}, //
+ ".xaml": {Icon: "\uf0673", Color: 56}, //
".xcf": {Icon: "\uf338", Color: 240}, //
+ ".xcplayground": {Icon: "\ue755", Color: 166}, //
+ ".xcstrings": {Icon: "\U000f05ca", Color: 31}, //
".xhtml": {Icon: "\uf13b", Color: 196}, //
+ ".x": {Icon: "\ue691", Color: 111}, //
".xls": {Icon: "\uf1c3", Color: 34}, //
".xlsx": {Icon: "\uf1c3", Color: 34}, //
+ ".xm": {Icon: "\ue691", Color: 74}, //
".xml": {Icon: "\uf121", Color: 160}, //
".xpi": {Icon: "\ueae6", Color: 17}, //
".xul": {Icon: "\uf121", Color: 166}, //
@@ -451,8 +595,8 @@ var extIconMap = map[string]IconProperties{
".zig": {Icon: "\ue6a9", Color: 172}, //
".zip": {Icon: "\uf410", Color: 241}, //
".zsh": {Icon: "\ue795", Color: 241}, //
- ".zsh-theme": {Icon: "\ue795", Color: 241}, //
".zshrc": {Icon: "\ue795", Color: 241}, //
+ ".zsh-theme": {Icon: "\ue795", Color: 241}, //
".zst": {Icon: "\uf410", Color: 241}, //
}
From cd01e4e7c2639c061e319df024917ca469690172 Mon Sep 17 00:00:00 2001
From: hasecilu
Date: Mon, 8 Jul 2024 11:46:20 -0600
Subject: [PATCH 21/36] fixup! Add icons for some file names
---
pkg/gui/presentation/icons/file_icons.go | 236 +++++++++++++++++------
1 file changed, 174 insertions(+), 62 deletions(-)
diff --git a/pkg/gui/presentation/icons/file_icons.go b/pkg/gui/presentation/icons/file_icons.go
index f0fcb69e6..8f639a4ee 100644
--- a/pkg/gui/presentation/icons/file_icons.go
+++ b/pkg/gui/presentation/icons/file_icons.go
@@ -15,68 +15,180 @@ var (
)
var nameIconMap = map[string]IconProperties{
- ".Trash": {Icon: "\uf1f8", Color: 241}, //
- ".atom": {Icon: "\ue764", Color: 241}, //
- ".bashprofile": {Icon: "\ue615", Color: 113}, //
- ".bashrc": {Icon: "\ue795", Color: 113}, //
- ".idea": {Icon: "\ue7b5", Color: 241}, //
- ".git": {Icon: "\uf1d3", Color: 202}, //
- ".gitattributes": {Icon: "\uf1d3", Color: 202}, //
- ".gitconfig": {Icon: "\uf1d3", Color: 202}, //
- ".github": {Icon: "\uf408", Color: 241}, //
- ".gitignore": {Icon: "\uf1d3", Color: 202}, //
- ".gitmodules": {Icon: "\uf1d3", Color: 202}, //
- ".mailmap": {Icon: "\uf1d3", Color: 202}, //
- ".npmrc": {Icon: "\ue71e", Color: 197}, //
- ".prettierrc": {Icon: "\ue6b4", Color: 33}, //
- ".rvm": {Icon: "\ue21e", Color: 160}, //
- ".SRCINFO": {Icon: "\uf129", Color: 230}, //
- ".vimrc": {Icon: "\ue62b", Color: 28}, //
- ".vscode": {Icon: "\ue70c", Color: 39}, //
- ".Xauthority": {Icon: "\uf369", Color: 196}, //
- ".xinitrc": {Icon: "\uf369", Color: 196}, //
- ".Xresources": {Icon: "\uf369", Color: 196}, //
- ".xsession": {Icon: "\uf369", Color: 196}, //
- ".zshrc": {Icon: "\ue795", Color: 113}, //
- "bin": {Icon: "\ue5fc", Color: 241}, //
- "Cargo.lock": {Icon: "\ue7a8", Color: 216}, //
- "Cargo.toml": {Icon: "\ue7a8", Color: 216}, //
- "COMMIT_EDITMSG": {Icon: "\ue702", Color: 239}, //
- "compose.yaml": {Icon: "\uf308", Color: 68}, //
- "compose.yml": {Icon: "\uf308", Color: 68}, //
- "config": {Icon: "\ue5fc", Color: 241}, //
- "docker-compose.yml": {Icon: "\uf308", Color: 68}, //
- "docker-compose.yaml":{Icon: "\uf308", Color: 68}, //
- "Dockerfile": {Icon: "\uf308", Color: 68}, //
- "ds_store": {Icon: "\uf179", Color: 15}, //
- "favicon.ico": {Icon: "\ue623", Color: 185}, //
- "fp-info-cache": {Icon: "\uf49b", Color: 231}, //
- "fp-lib-table": {Icon: "\uf34c", Color: 231}, //
- "gitignore_global": {Icon: "\uf1d3", Color: 202}, //
- "GNUmakefile": {Icon: "\ue779", Color: 66}, //
- "go.mod": {Icon: "\ue627", Color: 74}, //
- "go.sum": {Icon: "\ue627", Color: 74}, //
- "gradle": {Icon: "\ue256", Color: 168}, //
- "gruntfile.coffee": {Icon: "\ue611", Color: 166}, //
- "gruntfile.js": {Icon: "\ue611", Color: 166}, //
- "gruntfile.ls": {Icon: "\ue611", Color: 166}, //
- "gtkrc": {Icon: "\uf362", Color: 231}, //
- "gulpfile.coffee": {Icon: "\ue610", Color: 167}, //
- "gulpfile.js": {Icon: "\ue610", Color: 167}, //
- "gulpfile.ls": {Icon: "\ue610", Color: 168}, //
- "hidden": {Icon: "\uf023", Color: 241}, //
- "include": {Icon: "\ue5fc", Color: 241}, //
- "lib": {Icon: "\uf121", Color: 241}, //
- "localized": {Icon: "\uf179", Color: 15}, //
- "Makefile": {Icon: "\ue975", Color: 241}, //
- "node_modules": {Icon: "\ue718", Color: 197}, //
- "npmignore": {Icon: "\ue71e", Color: 197}, //
- "PKGBUILD": {Icon: "\uf303", Color: 38}, //
- "rubydoc": {Icon: "\ue73b", Color: 160}, //
- "sym-lib-table": {Icon: "\uf34c", Color: 231}, //
- "xorg.conf": {Icon: "\uf369", Color: 196}, //
- "xsettingsd.conf": {Icon: "\uf369", Color: 196}, //
- "yarn.lock": {Icon: "\ue6a7", Color: 74}, //
+ ".atom": {Icon: "\ue764", Color: 241}, //
+ ".babelrc": {Icon: "\ue639", Color: 185}, //
+ ".bash_profile": {Icon: "\ue615", Color: 113}, //
+ ".bashprofile": {Icon: "\ue615", Color: 113}, //
+ ".bashrc": {Icon: "\ue795", Color: 113}, //
+ ".dockerignore": {Icon: "\uf0868", Color: 68}, //
+ ".ds_store": {Icon: "\ue615", Color: 239}, //
+ ".editorconfig": {Icon: "\ue652", Color: 255}, //
+ ".env": {Icon: "\uf462", Color: 227}, //
+ ".eslintignore": {Icon: "\ue655", Color: 56}, //
+ ".eslintrc": {Icon: "\ue655", Color: 56}, //
+ ".gitattributes": {Icon: "\U000f02a2", Color: 202}, //
+ ".git-blame-ignore-revs": {Icon: "\ue702", Color: 196}, //
+ ".gitconfig": {Icon: "\U000f02a2", Color: 202}, //
+ ".github": {Icon: "\uf408", Color: 241}, //
+ ".git": {Icon: "\U000f02a2", Color: 202}, //
+ ".gitignore": {Icon: "\U000f02a2", Color: 202}, //
+ ".gitlab-ci.yml": {Icon: "\uf296", Color: 196}, //
+ ".gitmodules": {Icon: "\U000f02a2", Color: 202}, //
+ ".gtkrc-2.0": {Icon: "\uf362", Color: 231}, //
+ ".gvimrc": {Icon: "\ue62b", Color: 28}, //
+ "_gvimrc": {Icon: "\ue62b", Color: 28}, //
+ ".idea": {Icon: "\ue7b5", Color: 241}, //
+ ".justfile": {Icon: "\uf0ad", Color: 66}, //
+ ".luaurc": {Icon: "\ue615", Color: 75}, //
+ ".mailmap": {Icon: "\U000f02a2", Color: 202}, //
+ ".npmignore": {Icon: "\ue71e", Color: 197}, //
+ ".npmrc": {Icon: "\ue71e", Color: 197}, //
+ ".nuxtrc": {Icon: "\uf1106", Color: 42}, //
+ ".nvmrc": {Icon: "\ue718", Color: 71}, //
+ ".prettierignore": {Icon: "\ue6b4", Color: 33}, //
+ ".prettierrc": {Icon: "\ue6b4", Color: 33}, //
+ ".prettierrc.json5": {Icon: "\ue6b4", Color: 33}, //
+ ".prettierrc.json": {Icon: "\ue6b4", Color: 33}, //
+ ".prettierrc.toml": {Icon: "\ue6b4", Color: 33}, //
+ ".prettierrc.yaml": {Icon: "\ue6b4", Color: 33}, //
+ ".prettierrc.yml": {Icon: "\ue6b4", Color: 33}, //
+ ".rvm": {Icon: "\ue21e", Color: 160}, //
+ ".settings.json": {Icon: "\ue70c", Color: 98}, //
+ ".SRCINFO": {Icon: "\uf129", Color: 230}, //
+ ".Trash": {Icon: "\uf1f8", Color: 241}, //
+ ".vimrc": {Icon: "\ue62b", Color: 28}, //
+ "_vimrc": {Icon: "\ue62b", Color: 28}, //
+ ".vscode": {Icon: "\ue70c", Color: 39}, //
+ ".Xauthority": {Icon: "\uf369", Color: 196}, //
+ ".xinitrc": {Icon: "\uf369", Color: 196}, //
+ ".Xresources": {Icon: "\uf369", Color: 196}, //
+ ".xsession": {Icon: "\uf369", Color: 196}, //
+ ".zprofile": {Icon: "\ue615", Color: 113}, //
+ ".zshenv": {Icon: "\ue615", Color: 113}, //
+ ".zshrc": {Icon: "\ue795", Color: 113}, //
+ "bin": {Icon: "\ue5fc", Color: 241}, //
+ "brewfile": {Icon: "\ue791", Color: 52}, //
+ "bspwmrc": {Icon: "\uf355", Color: 236}, //
+ "build.gradle": {Icon: "\ue660", Color: 24}, //
+ "build": {Icon: "\ue63a", Color: 113}, //
+ "build.zig.zon": {Icon: "\ue6a9", Color: 172}, //
+ "cantorrc": {Icon: "\uf373", Color: 32}, //
+ "Cargo.lock": {Icon: "\ue7a8", Color: 216}, //
+ "Cargo.toml": {Icon: "\ue7a8", Color: 216}, //
+ "checkhealth": {Icon: "\uf04d9", Color: 75}, //
+ "cmakelists.txt": {Icon: "\ue615", Color: 66}, //
+ "commit_editmsg": {Icon: "\ue702", Color: 196}, //
+ "COMMIT_EDITMSG": {Icon: "\ue702", Color: 239}, //
+ "commitlint.config.js": {Icon: "\uf0718", Color: 30}, //
+ "commitlint.config.ts": {Icon: "\uf0718", Color: 30}, //
+ "compose.yaml": {Icon: "\uf308", Color: 68}, //
+ "compose.yml": {Icon: "\uf308", Color: 68}, //
+ "config": {Icon: "\ue5fc", Color: 241}, //
+ "containerfile": {Icon: "\uf0868", Color: 68}, //
+ "copying": {Icon: "\ue60a", Color: 185}, //
+ "copying.lesser": {Icon: "\ue60a", Color: 185}, //
+ "docker-compose.yaml": {Icon: "\uf308", Color: 68}, //
+ "docker-compose.yml": {Icon: "\uf308", Color: 68}, //
+ "dockerfile": {Icon: "\uf0868", Color: 68}, //
+ "Dockerfile": {Icon: "\uf308", Color: 68}, //
+ "ds_store": {Icon: "\uf179", Color: 15}, //
+ "eslint.config.cjs": {Icon: "\ue655", Color: 56}, //
+ "eslint.config.js": {Icon: "\ue655", Color: 56}, //
+ "eslint.config.mjs": {Icon: "\ue655", Color: 56}, //
+ "eslint.config.ts": {Icon: "\ue655", Color: 56}, //
+ "ext_typoscript_setup.txt": {Icon: "\ue772", Color: 208}, //
+ "favicon.ico": {Icon: "\ue623", Color: 185}, //
+ "fp-info-cache": {Icon: "\uf49b", Color: 231}, //
+ "fp-lib-table": {Icon: "\uf34c", Color: 231}, //
+ "FreeCAD.conf": {Icon: "\uf336", Color: 160}, //
+ "gemfile$": {Icon: "\ue791", Color: 52}, //
+ "gitignore_global": {Icon: "\U000f02a2", Color: 202}, //
+ "gnumakefile": {Icon: "\ue779", Color: 66}, //
+ "GNUmakefile": {Icon: "\ue779", Color: 66}, //
+ "go.mod": {Icon: "\ue627", Color: 74}, //
+ "go.sum": {Icon: "\ue627", Color: 74}, //
+ "go.work": {Icon: "\ue627", Color: 74}, //
+ "gradle": {Icon: "\ue256", Color: 168}, //
+ "gradle.properties": {Icon: "\ue660", Color: 24}, //
+ "gradlew": {Icon: "\ue660", Color: 24}, //
+ "gradle-wrapper.properties": {Icon: "\ue660", Color: 24}, //
+ "gruntfile.babel.js": {Icon: "\ue611", Color: 166}, //
+ "gruntfile.coffee": {Icon: "\ue611", Color: 166}, //
+ "gruntfile.js": {Icon: "\ue611", Color: 166}, //
+ "gruntfile.ls": {Icon: "\ue611", Color: 166}, //
+ "gruntfile.ts": {Icon: "\ue611", Color: 166}, //
+ "gtkrc": {Icon: "\uf362", Color: 231}, //
+ "gulpfile.babel.js": {Icon: "\ue610", Color: 167}, //
+ "gulpfile.coffee": {Icon: "\ue610", Color: 167}, //
+ "gulpfile.js": {Icon: "\ue610", Color: 167}, //
+ "gulpfile.ls": {Icon: "\ue610", Color: 168}, //
+ "gulpfile.ts": {Icon: "\ue610", Color: 167}, //
+ "hidden": {Icon: "\uf023", Color: 241}, //
+ "hypridle.conf": {Icon: "\uf359", Color: 37}, //
+ "hyprland.conf": {Icon: "\uf359", Color: 37}, //
+ "hyprlock.conf": {Icon: "\uf359", Color: 37}, //
+ "i3blocks.conf": {Icon: "\uf35a", Color: 255}, //
+ "i3status.conf": {Icon: "\uf35a", Color: 255}, //
+ "include": {Icon: "\ue5fc", Color: 241}, //
+ "ionic.config.json": {Icon: "\ue7a9", Color: 33}, //
+ "justfile": {Icon: "\uf0ad", Color: 66}, //
+ "kalgebrarc": {Icon: "\uf373", Color: 32}, //
+ "kdeglobals": {Icon: "\uf373", Color: 32}, //
+ "kdenlive-layoutsrc": {Icon: "\uf33c", Color: 110}, //
+ "kdenliverc": {Icon: "\uf33c", Color: 110}, //
+ "kritadisplayrc": {Icon: "\uf33d", Color: 201}, //
+ "kritarc": {Icon: "\uf33d", Color: 201}, //
+ "lib": {Icon: "\uf121", Color: 241}, //
+ "localized": {Icon: "\uf179", Color: 15}, //
+ "lxde-rc.xml": {Icon: "\uf363", Color: 246}, //
+ "lxqt.conf": {Icon: "\uf364", Color: 32}, //
+ "Makefile": {Icon: "\ue975", Color: 241}, //
+ "mix.lock": {Icon: "\ue62d", Color: 140}, //
+ "mpv.conf": {Icon: "\uf36e", Color: 53}, //
+ "node_modules": {Icon: "\ue718", Color: 197}, //
+ "npmignore": {Icon: "\ue71e", Color: 197}, //
+ "nuxt.config.cjs": {Icon: "\uf1106", Color: 42}, //
+ "nuxt.config.js": {Icon: "\uf1106", Color: 42}, //
+ "nuxt.config.mjs": {Icon: "\uf1106", Color: 42}, //
+ "nuxt.config.ts": {Icon: "\uf1106", Color: 42}, //
+ "package.json": {Icon: "\ue71e", Color: 197}, //
+ "package-lock.json": {Icon: "\ue71e", Color: 52}, //
+ "PKGBUILD": {Icon: "\uf303", Color: 38}, //
+ "platformio.ini": {Icon: "\ue682", Color: 208}, //
+ "pom.xml": {Icon: "\ue674", Color: 52}, //
+ "prettier.config.cjs": {Icon: "\ue6b4", Color: 33}, //
+ "prettier.config.js": {Icon: "\ue6b4", Color: 33}, //
+ "prettier.config.mjs": {Icon: "\ue6b4", Color: 33}, //
+ "prettier.config.ts": {Icon: "\ue6b4", Color: 33}, //
+ "PrusaSlicerGcodeViewer.ini": {Icon: "\uf351", Color: 202}, //
+ "PrusaSlicer.ini": {Icon: "\uf351", Color: 202}, //
+ "py.typed": {Icon: "\ue606", Color: 214}, //
+ "QtProject.conf": {Icon: "\uf375", Color: 77}, //
+ "R": {Icon: "\uf07d4", Color: 25}, //
+ "robots.txt": {Icon: "\uf06a9", Color: 60}, //
+ "rubydoc": {Icon: "\ue73b", Color: 160}, //
+ "settings.gradle": {Icon: "\ue660", Color: 24}, //
+ "svelte.config.js": {Icon: "\ue697", Color: 196}, //
+ "sxhkdrc": {Icon: "\uf355", Color: 236}, //
+ "sym-lib-table": {Icon: "\uf34c", Color: 231}, //
+ "tailwind.config.js": {Icon: "\uf13ff", Color: 45}, //
+ "tailwind.config.mjs": {Icon: "\uf13ff", Color: 45}, //
+ "tailwind.config.ts": {Icon: "\uf13ff", Color: 45}, //
+ "tmux.conf": {Icon: "\uebc8", Color: 34}, //
+ "tmux.conf.local": {Icon: "\uebc8", Color: 34}, //
+ "tsconfig.json": {Icon: "\ue69d", Color: 74}, //
+ "unlicense": {Icon: "\ue60a", Color: 185}, //
+ "vagrantfile$": {Icon: "\uf2b8", Color: 27}, //
+ "vlcrc": {Icon: "\uf057c", Color: 208}, //
+ "webpack": {Icon: "\uf072b", Color: 74}, //
+ "weston.ini": {Icon: "\uf367", Color: 214}, //
+ "workspace": {Icon: "\ue63a", Color: 113}, //
+ "xmobarrc.hs": {Icon: "\uf35e", Color: 203}, //
+ "xmobarrc": {Icon: "\uf35e", Color: 203}, //
+ "xmonad.hs": {Icon: "\uf35e", Color: 203}, //
+ "xorg.conf": {Icon: "\uf369", Color: 196}, //
+ "xsettingsd.conf": {Icon: "\uf369", Color: 196}, //
+ "yarn.lock": {Icon: "\ue6a7", Color: 74}, //
}
var extIconMap = map[string]IconProperties{
From 7652d579f587c3202d1d80464557cfaa8005b3de Mon Sep 17 00:00:00 2001
From: Jesse Duffield
Date: Sat, 13 Jul 2024 13:34:35 +1000
Subject: [PATCH 22/36] Check for fixup commits on CI
I keep merging PRs that still have fixup commits on them! This will make
it impossible to do so
---
.github/workflows/ci.yml | 22 ++++++++++++++++++++++
scripts/check_for_fixups.sh | 25 +++++++++++++++++++++++++
2 files changed, 47 insertions(+)
create mode 100755 scripts/check_for_fixups.sh
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 64c890894..9b0a04938 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -219,3 +219,25 @@ jobs:
CODACY_PROJECT_TOKEN=${{ secrets.CODACY_PROJECT_TOKEN }} \
bash <(curl -Ls https://coverage.codacy.com/get.sh) report \
--force-coverage-parser go -r coverage.out
+
+ check-for-fixups:
+ runs-on: ubuntu-latest
+ if: github.ref != 'refs/heads/master'
+ steps:
+ # See https://github.com/actions/checkout/issues/552#issuecomment-1167086216
+ - name: "PR commits + 1"
+ run: echo "PR_FETCH_DEPTH=$(( ${{ github.event.pull_request.commits }} + 1 ))" >> "${GITHUB_ENV}"
+
+ - name: "Checkout PR branch and all PR commits"
+ uses: actions/checkout@v4
+ with:
+ ref: ${{ github.event.pull_request.head.ref }}
+ fetch-depth: ${{ env.PR_FETCH_DEPTH }}
+
+ - name: "Fetch the other branch with enough history for a common merge-base commit"
+ run: |
+ git fetch origin ${{ github.event.pull_request.base.ref }}
+
+ - name: Check for fixups
+ run: |
+ ./scripts/check_for_fixups.sh ${{ github.event.pull_request.base.ref }}
diff --git a/scripts/check_for_fixups.sh b/scripts/check_for_fixups.sh
new file mode 100755
index 000000000..c2c2e1a21
--- /dev/null
+++ b/scripts/check_for_fixups.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+base_ref=$1
+
+# Determine the base commit
+base_commit=$(git merge-base HEAD origin/"$base_ref")
+
+# Check if base_commit is set correctly
+if [ -z "$base_commit" ]; then
+ echo "Failed to determine base commit."
+ exit 1
+fi
+echo "Base commit: $base_commit"
+
+# Get commits with "fixup!" in the message from base_commit to HEAD
+commits=$(git log -i -P --grep "fixup\!" --format="%h %s" "$base_commit..HEAD")
+
+if [ -z "$commits" ]; then
+ echo "No fixup commits found."
+ exit 0
+else
+ echo "Fixup commits found:"
+ echo "$commits"
+ exit 1
+fi
From b9107d5fc8ff941456b26accfefeffe0f81e8d11 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Istv=C3=A1n=20Donk=C3=B3?=
Date: Mon, 25 Sep 2023 17:32:12 +0200
Subject: [PATCH 23/36] Support setting the similarity threshold for detecting
renames
---
docs/Config.md | 2 +
docs/keybindings/Keybindings_en.md | 2 +
docs/keybindings/Keybindings_ja.md | 2 +
docs/keybindings/Keybindings_ko.md | 2 +
docs/keybindings/Keybindings_nl.md | 2 +
docs/keybindings/Keybindings_pl.md | 2 +
docs/keybindings/Keybindings_ru.md | 2 +
docs/keybindings/Keybindings_zh-CN.md | 2 +
docs/keybindings/Keybindings_zh-TW.md | 2 +
pkg/commands/git_commands/commit.go | 1 +
pkg/commands/git_commands/commit_test.go | 88 +-
pkg/commands/git_commands/file_loader.go | 10 +-
pkg/commands/git_commands/file_loader_test.go | 28 +-
pkg/commands/git_commands/stash.go | 1 +
pkg/commands/git_commands/stash_test.go | 53 +-
pkg/commands/git_commands/working_tree.go | 1 +
.../git_commands/working_tree_test.go | 97 ++-
pkg/config/app_config.go | 20 +-
pkg/config/user_config.go | 272 +++----
pkg/gui/controllers.go | 2 +
.../rename_similarity_threshold_controller.go | 100 +++
pkg/i18n/english.go | 750 +++++++++---------
.../rename_similarity_threshold_change.go | 41 +
.../rename_similarity_threshold_change.go | 35 +
pkg/integration/tests/test_list.go | 2 +
schema/config.json | 8 +
26 files changed, 909 insertions(+), 618 deletions(-)
create mode 100644 pkg/gui/controllers/rename_similarity_threshold_controller.go
create mode 100644 pkg/integration/tests/diff/rename_similarity_threshold_change.go
create mode 100644 pkg/integration/tests/file/rename_similarity_threshold_change.go
diff --git a/docs/Config.md b/docs/Config.md
index 03501e8c2..be579ae8b 100644
--- a/docs/Config.md
+++ b/docs/Config.md
@@ -521,6 +521,8 @@ keybinding:
toggleWhitespaceInDiffView:
increaseContextInDiffView: '}'
decreaseContextInDiffView: '{'
+ increaseRenameSimilarityThreshold: )
+ decreaseRenameSimilarityThreshold: (
openDiffTool:
status:
checkForUpdate: u
diff --git a/docs/keybindings/Keybindings_en.md b/docs/keybindings/Keybindings_en.md
index eb88cb182..47ae9cfb5 100644
--- a/docs/keybindings/Keybindings_en.md
+++ b/docs/keybindings/Keybindings_en.md
@@ -14,6 +14,8 @@ _Legend: `` means ctrl+b, `` means alt+b, `B` means shift+b_
| `` @ `` | View command log options | View options for the command log e.g. show/hide the command log and focus the command log. |
| `` P `` | Push | Push the current branch to its upstream branch. If no upstream is configured, you will be prompted to configure an upstream branch. |
| `` p `` | Pull | Pull changes from the remote for the current branch. If no upstream is configured, you will be prompted to configure an upstream branch. |
+| `` ) `` | Increase rename similarity threshold | Increase the similarity threshold for a deletion and addition pair to be treated as a rename. |
+| `` ( `` | Decrease rename similarity threshold | Decrease the similarity threshold for a deletion and addition pair to be treated as a rename. |
| `` } `` | Increase diff context size | Increase the amount of the context shown around changes in the diff view. |
| `` { `` | Decrease diff context size | Decrease the amount of the context shown around changes in the diff view. |
| `` : `` | Execute custom command | Bring up a prompt where you can enter a shell command to execute. Not to be confused with pre-configured custom commands. |
diff --git a/docs/keybindings/Keybindings_ja.md b/docs/keybindings/Keybindings_ja.md
index 9a146261b..d72096f62 100644
--- a/docs/keybindings/Keybindings_ja.md
+++ b/docs/keybindings/Keybindings_ja.md
@@ -14,6 +14,8 @@ _Legend: `` means ctrl+b, `` means alt+b, `B` means shift+b_
| `` @ `` | コマンドログメニューを開く | View options for the command log e.g. show/hide the command log and focus the command log. |
| `` P `` | Push | Push the current branch to its upstream branch. If no upstream is configured, you will be prompted to configure an upstream branch. |
| `` p `` | Pull | Pull changes from the remote for the current branch. If no upstream is configured, you will be prompted to configure an upstream branch. |
+| `` ) `` | Increase rename similarity threshold | Increase the similarity threshold for a deletion and addition pair to be treated as a rename. |
+| `` ( `` | Decrease rename similarity threshold | Decrease the similarity threshold for a deletion and addition pair to be treated as a rename. |
| `` } `` | Increase diff context size | Increase the amount of the context shown around changes in the diff view. |
| `` { `` | Decrease diff context size | Decrease the amount of the context shown around changes in the diff view. |
| `` : `` | カスタムコマンドを実行 | Bring up a prompt where you can enter a shell command to execute. Not to be confused with pre-configured custom commands. |
diff --git a/docs/keybindings/Keybindings_ko.md b/docs/keybindings/Keybindings_ko.md
index 289f6931f..7c4e9c9f4 100644
--- a/docs/keybindings/Keybindings_ko.md
+++ b/docs/keybindings/Keybindings_ko.md
@@ -14,6 +14,8 @@ _Legend: `` means ctrl+b, `` means alt+b, `B` means shift+b_
| `` @ `` | 명령어 로그 메뉴 열기 | View options for the command log e.g. show/hide the command log and focus the command log. |
| `` P `` | 푸시 | Push the current branch to its upstream branch. If no upstream is configured, you will be prompted to configure an upstream branch. |
| `` p `` | 업데이트 | Pull changes from the remote for the current branch. If no upstream is configured, you will be prompted to configure an upstream branch. |
+| `` ) `` | Increase rename similarity threshold | Increase the similarity threshold for a deletion and addition pair to be treated as a rename. |
+| `` ( `` | Decrease rename similarity threshold | Decrease the similarity threshold for a deletion and addition pair to be treated as a rename. |
| `` } `` | Diff 보기의 변경 사항 주위에 표시되는 컨텍스트의 크기를 늘리기 | Increase the amount of the context shown around changes in the diff view. |
| `` { `` | Diff 보기의 변경 사항 주위에 표시되는 컨텍스트 크기 줄이기 | Decrease the amount of the context shown around changes in the diff view. |
| `` : `` | Execute custom command | Bring up a prompt where you can enter a shell command to execute. Not to be confused with pre-configured custom commands. |
diff --git a/docs/keybindings/Keybindings_nl.md b/docs/keybindings/Keybindings_nl.md
index 03bf0214c..60cbf54e9 100644
--- a/docs/keybindings/Keybindings_nl.md
+++ b/docs/keybindings/Keybindings_nl.md
@@ -14,6 +14,8 @@ _Legend: `` means ctrl+b, `` means alt+b, `B` means shift+b_
| `` @ `` | View command log options | View options for the command log e.g. show/hide the command log and focus the command log. |
| `` P `` | Push | Push the current branch to its upstream branch. If no upstream is configured, you will be prompted to configure an upstream branch. |
| `` p `` | Pull | Pull changes from the remote for the current branch. If no upstream is configured, you will be prompted to configure an upstream branch. |
+| `` ) `` | Increase rename similarity threshold | Increase the similarity threshold for a deletion and addition pair to be treated as a rename. |
+| `` ( `` | Decrease rename similarity threshold | Decrease the similarity threshold for a deletion and addition pair to be treated as a rename. |
| `` } `` | Increase diff context size | Increase the amount of the context shown around changes in the diff view. |
| `` { `` | Decrease diff context size | Decrease the amount of the context shown around changes in the diff view. |
| `` : `` | Voer aangepaste commando uit | Bring up a prompt where you can enter a shell command to execute. Not to be confused with pre-configured custom commands. |
diff --git a/docs/keybindings/Keybindings_pl.md b/docs/keybindings/Keybindings_pl.md
index 0336419c1..7d2d7e561 100644
--- a/docs/keybindings/Keybindings_pl.md
+++ b/docs/keybindings/Keybindings_pl.md
@@ -14,6 +14,8 @@ _Legenda: `` oznacza ctrl+b, `` oznacza alt+b, `B` oznacza shift+b_
| `` @ `` | Pokaż opcje dziennika poleceń | Pokaż opcje dla dziennika poleceń, np. pokazywanie/ukrywanie dziennika poleceń i skupienie na dzienniku poleceń. |
| `` P `` | Wypchnij | Wypchnij bieżącą gałąź do jej gałęzi nadrzędnej. Jeśli nie skonfigurowano gałęzi nadrzędnej, zostaniesz poproszony o skonfigurowanie gałęzi nadrzędnej. |
| `` p `` | Pociągnij | Pociągnij zmiany z zdalnego dla bieżącej gałęzi. Jeśli nie skonfigurowano gałęzi nadrzędnej, zostaniesz poproszony o skonfigurowanie gałęzi nadrzędnej. |
+| `` ) `` | Increase rename similarity threshold | Increase the similarity threshold for a deletion and addition pair to be treated as a rename. |
+| `` ( `` | Decrease rename similarity threshold | Decrease the similarity threshold for a deletion and addition pair to be treated as a rename. |
| `` } `` | Zwiększ rozmiar kontekstu w widoku różnic | Zwiększ ilość kontekstu pokazywanego wokół zmian w widoku różnic. |
| `` { `` | Zmniejsz rozmiar kontekstu w widoku różnic | Zmniejsz ilość kontekstu pokazywanego wokół zmian w widoku różnic. |
| `` : `` | Wykonaj polecenie niestandardowe | Wyświetl monit, w którym możesz wprowadzić polecenie powłoki do wykonania. Nie należy mylić z wcześniej skonfigurowanymi poleceniami niestandardowymi. |
diff --git a/docs/keybindings/Keybindings_ru.md b/docs/keybindings/Keybindings_ru.md
index c6a784b72..ab49f2ab3 100644
--- a/docs/keybindings/Keybindings_ru.md
+++ b/docs/keybindings/Keybindings_ru.md
@@ -14,6 +14,8 @@ _Связки клавиш_
| `` @ `` | Открыть меню журнала команд | View options for the command log e.g. show/hide the command log and focus the command log. |
| `` P `` | Отправить изменения | Push the current branch to its upstream branch. If no upstream is configured, you will be prompted to configure an upstream branch. |
| `` p `` | Получить и слить изменения | Pull changes from the remote for the current branch. If no upstream is configured, you will be prompted to configure an upstream branch. |
+| `` ) `` | Increase rename similarity threshold | Increase the similarity threshold for a deletion and addition pair to be treated as a rename. |
+| `` ( `` | Decrease rename similarity threshold | Decrease the similarity threshold for a deletion and addition pair to be treated as a rename. |
| `` } `` | Увеличить размер контекста, отображаемого вокруг изменений в просмотрщике сравнении | Increase the amount of the context shown around changes in the diff view. |
| `` { `` | Уменьшите размер контекста, отображаемого вокруг изменений в просмотрщике сравнении | Decrease the amount of the context shown around changes in the diff view. |
| `` : `` | Выполнить пользовательскую команду | Bring up a prompt where you can enter a shell command to execute. Not to be confused with pre-configured custom commands. |
diff --git a/docs/keybindings/Keybindings_zh-CN.md b/docs/keybindings/Keybindings_zh-CN.md
index 8cb93e519..c91cdc8e8 100644
--- a/docs/keybindings/Keybindings_zh-CN.md
+++ b/docs/keybindings/Keybindings_zh-CN.md
@@ -14,6 +14,8 @@ _Legend: `` means ctrl+b, `` means alt+b, `B` means shift+b_
| `` @ `` | 打开命令日志菜单 | View options for the command log e.g. show/hide the command log and focus the command log. |
| `` P `` | 推送 | Push the current branch to its upstream branch. If no upstream is configured, you will be prompted to configure an upstream branch. |
| `` p `` | 拉取 | Pull changes from the remote for the current branch. If no upstream is configured, you will be prompted to configure an upstream branch. |
+| `` ) `` | Increase rename similarity threshold | Increase the similarity threshold for a deletion and addition pair to be treated as a rename. |
+| `` ( `` | Decrease rename similarity threshold | Decrease the similarity threshold for a deletion and addition pair to be treated as a rename. |
| `` } `` | 扩大差异视图中显示的上下文范围 | Increase the amount of the context shown around changes in the diff view. |
| `` { `` | 缩小差异视图中显示的上下文范围 | Decrease the amount of the context shown around changes in the diff view. |
| `` : `` | 执行自定义命令 | Bring up a prompt where you can enter a shell command to execute. Not to be confused with pre-configured custom commands. |
diff --git a/docs/keybindings/Keybindings_zh-TW.md b/docs/keybindings/Keybindings_zh-TW.md
index d82e3361d..dccba00dc 100644
--- a/docs/keybindings/Keybindings_zh-TW.md
+++ b/docs/keybindings/Keybindings_zh-TW.md
@@ -14,6 +14,8 @@ _說明:`` 表示 Ctrl+B、`` 表示 Alt+B,`B`表示 Shift+B
| `` @ `` | 開啟命令記錄選單 | View options for the command log e.g. show/hide the command log and focus the command log. |
| `` P `` | 推送 | Push the current branch to its upstream branch. If no upstream is configured, you will be prompted to configure an upstream branch. |
| `` p `` | 拉取 | Pull changes from the remote for the current branch. If no upstream is configured, you will be prompted to configure an upstream branch. |
+| `` ) `` | Increase rename similarity threshold | Increase the similarity threshold for a deletion and addition pair to be treated as a rename. |
+| `` ( `` | Decrease rename similarity threshold | Decrease the similarity threshold for a deletion and addition pair to be treated as a rename. |
| `` } `` | 增加差異檢視中顯示變更周圍上下文的大小 | Increase the amount of the context shown around changes in the diff view. |
| `` { `` | 減小差異檢視中顯示變更周圍上下文的大小 | Decrease the amount of the context shown around changes in the diff view. |
| `` : `` | 執行自訂命令 | Bring up a prompt where you can enter a shell command to execute. Not to be confused with pre-configured custom commands. |
diff --git a/pkg/commands/git_commands/commit.go b/pkg/commands/git_commands/commit.go
index 517be276e..4153dfeb9 100644
--- a/pkg/commands/git_commands/commit.go
+++ b/pkg/commands/git_commands/commit.go
@@ -271,6 +271,7 @@ func (self *CommitCommands) ShowCmdObj(hash string, filterPath string) oscommand
Arg("-p").
Arg(hash).
ArgIf(self.AppState.IgnoreWhitespaceInDiffView, "--ignore-all-space").
+ Arg(fmt.Sprintf("--find-renames=%d%%", self.AppState.RenameSimilarityThreshold)).
ArgIf(filterPath != "", "--", filterPath).
Dir(self.repoPaths.worktreePath).
ToArgv()
diff --git a/pkg/commands/git_commands/commit_test.go b/pkg/commands/git_commands/commit_test.go
index c3708422e..239d7fa8f 100644
--- a/pkg/commands/git_commands/commit_test.go
+++ b/pkg/commands/git_commands/commit_test.go
@@ -228,54 +228,69 @@ func TestCommitCreateAmendCommit(t *testing.T) {
func TestCommitShowCmdObj(t *testing.T) {
type scenario struct {
- testName string
- filterPath string
- contextSize int
- ignoreWhitespace bool
- extDiffCmd string
- expected []string
+ testName string
+ filterPath string
+ contextSize int
+ similarityThreshold int
+ ignoreWhitespace bool
+ extDiffCmd string
+ expected []string
}
scenarios := []scenario{
{
- testName: "Default case without filter path",
- filterPath: "",
- contextSize: 3,
- ignoreWhitespace: false,
- extDiffCmd: "",
- expected: []string{"-C", "/path/to/worktree", "-c", "diff.noprefix=false", "show", "--no-ext-diff", "--submodule", "--color=always", "--unified=3", "--stat", "--decorate", "-p", "1234567890"},
+ testName: "Default case without filter path",
+ filterPath: "",
+ contextSize: 3,
+ similarityThreshold: 50,
+ ignoreWhitespace: false,
+ extDiffCmd: "",
+ expected: []string{"-C", "/path/to/worktree", "-c", "diff.noprefix=false", "show", "--no-ext-diff", "--submodule", "--color=always", "--unified=3", "--stat", "--decorate", "-p", "1234567890", "--find-renames=50%"},
},
{
- testName: "Default case with filter path",
- filterPath: "file.txt",
- contextSize: 3,
- ignoreWhitespace: false,
- extDiffCmd: "",
- expected: []string{"-C", "/path/to/worktree", "-c", "diff.noprefix=false", "show", "--no-ext-diff", "--submodule", "--color=always", "--unified=3", "--stat", "--decorate", "-p", "1234567890", "--", "file.txt"},
+ testName: "Default case with filter path",
+ filterPath: "file.txt",
+ contextSize: 3,
+ similarityThreshold: 50,
+ ignoreWhitespace: false,
+ extDiffCmd: "",
+ expected: []string{"-C", "/path/to/worktree", "-c", "diff.noprefix=false", "show", "--no-ext-diff", "--submodule", "--color=always", "--unified=3", "--stat", "--decorate", "-p", "1234567890", "--find-renames=50%", "--", "file.txt"},
},
{
- testName: "Show diff with custom context size",
- filterPath: "",
- contextSize: 77,
- ignoreWhitespace: false,
- extDiffCmd: "",
- expected: []string{"-C", "/path/to/worktree", "-c", "diff.noprefix=false", "show", "--no-ext-diff", "--submodule", "--color=always", "--unified=77", "--stat", "--decorate", "-p", "1234567890"},
+ testName: "Show diff with custom context size",
+ filterPath: "",
+ contextSize: 77,
+ similarityThreshold: 50,
+ ignoreWhitespace: false,
+ extDiffCmd: "",
+ expected: []string{"-C", "/path/to/worktree", "-c", "diff.noprefix=false", "show", "--no-ext-diff", "--submodule", "--color=always", "--unified=77", "--stat", "--decorate", "-p", "1234567890", "--find-renames=50%"},
},
{
- testName: "Show diff, ignoring whitespace",
- filterPath: "",
- contextSize: 77,
- ignoreWhitespace: true,
- extDiffCmd: "",
- expected: []string{"-C", "/path/to/worktree", "-c", "diff.noprefix=false", "show", "--no-ext-diff", "--submodule", "--color=always", "--unified=77", "--stat", "--decorate", "-p", "1234567890", "--ignore-all-space"},
+ testName: "Show diff with custom similarity threshold",
+ filterPath: "",
+ contextSize: 3,
+ similarityThreshold: 33,
+ ignoreWhitespace: false,
+ extDiffCmd: "",
+ expected: []string{"-C", "/path/to/worktree", "-c", "diff.noprefix=false", "show", "--no-ext-diff", "--submodule", "--color=always", "--unified=3", "--stat", "--decorate", "-p", "1234567890", "--find-renames=33%"},
},
{
- testName: "Show diff with external diff command",
- filterPath: "",
- contextSize: 3,
- ignoreWhitespace: false,
- extDiffCmd: "difft --color=always",
- expected: []string{"-C", "/path/to/worktree", "-c", "diff.external=difft --color=always", "-c", "diff.noprefix=false", "show", "--ext-diff", "--submodule", "--color=always", "--unified=3", "--stat", "--decorate", "-p", "1234567890"},
+ testName: "Show diff, ignoring whitespace",
+ filterPath: "",
+ contextSize: 77,
+ similarityThreshold: 50,
+ ignoreWhitespace: true,
+ extDiffCmd: "",
+ expected: []string{"-C", "/path/to/worktree", "-c", "diff.noprefix=false", "show", "--no-ext-diff", "--submodule", "--color=always", "--unified=77", "--stat", "--decorate", "-p", "1234567890", "--ignore-all-space", "--find-renames=50%"},
+ },
+ {
+ testName: "Show diff with external diff command",
+ filterPath: "",
+ contextSize: 3,
+ similarityThreshold: 50,
+ ignoreWhitespace: false,
+ extDiffCmd: "difft --color=always",
+ expected: []string{"-C", "/path/to/worktree", "-c", "diff.external=difft --color=always", "-c", "diff.noprefix=false", "show", "--ext-diff", "--submodule", "--color=always", "--unified=3", "--stat", "--decorate", "-p", "1234567890", "--find-renames=50%"},
},
}
@@ -286,6 +301,7 @@ func TestCommitShowCmdObj(t *testing.T) {
appState := &config.AppState{}
appState.IgnoreWhitespaceInDiffView = s.ignoreWhitespace
appState.DiffContextSize = s.contextSize
+ appState.RenameSimilarityThreshold = s.similarityThreshold
runner := oscommands.NewFakeRunner(t).ExpectGitArgs(s.expected, "", nil)
repoPaths := RepoPaths{
diff --git a/pkg/commands/git_commands/file_loader.go b/pkg/commands/git_commands/file_loader.go
index 73d7fdc64..72329543a 100644
--- a/pkg/commands/git_commands/file_loader.go
+++ b/pkg/commands/git_commands/file_loader.go
@@ -100,15 +100,19 @@ type FileStatus struct {
PreviousName string
}
-func (c *FileLoader) gitStatus(opts GitStatusOptions) ([]FileStatus, error) {
+func (self *FileLoader) gitStatus(opts GitStatusOptions) ([]FileStatus, error) {
cmdArgs := NewGitCmd("status").
Arg(opts.UntrackedFilesArg).
Arg("--porcelain").
Arg("-z").
- ArgIf(opts.NoRenames, "--no-renames").
+ ArgIfElse(
+ opts.NoRenames,
+ "--no-renames",
+ fmt.Sprintf("--find-renames=%d%%", self.AppState.RenameSimilarityThreshold),
+ ).
ToArgv()
- statusLines, _, err := c.cmd.New(cmdArgs).DontLog().RunWithOutputs()
+ statusLines, _, err := self.cmd.New(cmdArgs).DontLog().RunWithOutputs()
if err != nil {
return []FileStatus{}, err
}
diff --git a/pkg/commands/git_commands/file_loader_test.go b/pkg/commands/git_commands/file_loader_test.go
index 73fac7ef4..5a9f15700 100644
--- a/pkg/commands/git_commands/file_loader_test.go
+++ b/pkg/commands/git_commands/file_loader_test.go
@@ -5,27 +5,31 @@ import (
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
+ "github.com/jesseduffield/lazygit/pkg/config"
"github.com/stretchr/testify/assert"
)
func TestFileGetStatusFiles(t *testing.T) {
type scenario struct {
- testName string
- runner oscommands.ICmdObjRunner
- expectedFiles []*models.File
+ testName string
+ similarityThreshold int
+ runner oscommands.ICmdObjRunner
+ expectedFiles []*models.File
}
scenarios := []scenario{
{
"No files found",
+ 50,
oscommands.NewFakeRunner(t).
- ExpectGitArgs([]string{"status", "--untracked-files=yes", "--porcelain", "-z"}, "", nil),
+ ExpectGitArgs([]string{"status", "--untracked-files=yes", "--porcelain", "-z", "--find-renames=50%"}, "", nil),
[]*models.File{},
},
{
"Several files found",
+ 50,
oscommands.NewFakeRunner(t).
- ExpectGitArgs([]string{"status", "--untracked-files=yes", "--porcelain", "-z"},
+ ExpectGitArgs([]string{"status", "--untracked-files=yes", "--porcelain", "-z", "--find-renames=50%"},
"MM file1.txt\x00A file3.txt\x00AM file2.txt\x00?? file4.txt\x00UU file5.txt",
nil,
),
@@ -94,8 +98,9 @@ func TestFileGetStatusFiles(t *testing.T) {
},
{
"File with new line char",
+ 50,
oscommands.NewFakeRunner(t).
- ExpectGitArgs([]string{"status", "--untracked-files=yes", "--porcelain", "-z"}, "MM a\nb.txt", nil),
+ ExpectGitArgs([]string{"status", "--untracked-files=yes", "--porcelain", "-z", "--find-renames=50%"}, "MM a\nb.txt", nil),
[]*models.File{
{
Name: "a\nb.txt",
@@ -113,8 +118,9 @@ func TestFileGetStatusFiles(t *testing.T) {
},
{
"Renamed files",
+ 50,
oscommands.NewFakeRunner(t).
- ExpectGitArgs([]string{"status", "--untracked-files=yes", "--porcelain", "-z"},
+ ExpectGitArgs([]string{"status", "--untracked-files=yes", "--porcelain", "-z", "--find-renames=50%"},
"R after1.txt\x00before1.txt\x00RM after2.txt\x00before2.txt",
nil,
),
@@ -149,8 +155,9 @@ func TestFileGetStatusFiles(t *testing.T) {
},
{
"File with arrow in name",
+ 50,
oscommands.NewFakeRunner(t).
- ExpectGitArgs([]string{"status", "--untracked-files=yes", "--porcelain", "-z"},
+ ExpectGitArgs([]string{"status", "--untracked-files=yes", "--porcelain", "-z", "--find-renames=50%"},
`?? a -> b.txt`,
nil,
),
@@ -175,8 +182,11 @@ func TestFileGetStatusFiles(t *testing.T) {
t.Run(s.testName, func(t *testing.T) {
cmd := oscommands.NewDummyCmdObjBuilder(s.runner)
+ appState := &config.AppState{}
+ appState.RenameSimilarityThreshold = s.similarityThreshold
+
loader := &FileLoader{
- GitCommon: buildGitCommon(commonDeps{}),
+ GitCommon: buildGitCommon(commonDeps{appState: appState}),
cmd: cmd,
config: &FakeFileLoaderConfig{showUntrackedFiles: "yes"},
getFileType: func(string) string { return "file" },
diff --git a/pkg/commands/git_commands/stash.go b/pkg/commands/git_commands/stash.go
index 5eeaa6a68..047985e38 100644
--- a/pkg/commands/git_commands/stash.go
+++ b/pkg/commands/git_commands/stash.go
@@ -87,6 +87,7 @@ func (self *StashCommands) ShowStashEntryCmdObj(index int) oscommands.ICmdObj {
Arg(fmt.Sprintf("--color=%s", self.UserConfig.Git.Paging.ColorArg)).
Arg(fmt.Sprintf("--unified=%d", self.AppState.DiffContextSize)).
ArgIf(self.AppState.IgnoreWhitespaceInDiffView, "--ignore-all-space").
+ Arg(fmt.Sprintf("--find-renames=%d%%", self.AppState.RenameSimilarityThreshold)).
Arg(fmt.Sprintf("stash@{%d}", index)).
Dir(self.repoPaths.worktreePath).
ToArgv()
diff --git a/pkg/commands/git_commands/stash_test.go b/pkg/commands/git_commands/stash_test.go
index accd05890..207ddb126 100644
--- a/pkg/commands/git_commands/stash_test.go
+++ b/pkg/commands/git_commands/stash_test.go
@@ -98,34 +98,46 @@ func TestStashHash(t *testing.T) {
func TestStashStashEntryCmdObj(t *testing.T) {
type scenario struct {
- testName string
- index int
- contextSize int
- ignoreWhitespace bool
- expected []string
+ testName string
+ index int
+ contextSize int
+ similarityThreshold int
+ ignoreWhitespace bool
+ expected []string
}
scenarios := []scenario{
{
- testName: "Default case",
- index: 5,
- contextSize: 3,
- ignoreWhitespace: false,
- expected: []string{"git", "-C", "/path/to/worktree", "stash", "show", "-p", "--stat", "--color=always", "--unified=3", "stash@{5}"},
+ testName: "Default case",
+ index: 5,
+ contextSize: 3,
+ similarityThreshold: 50,
+ ignoreWhitespace: false,
+ expected: []string{"git", "-C", "/path/to/worktree", "stash", "show", "-p", "--stat", "--color=always", "--unified=3", "--find-renames=50%", "stash@{5}"},
},
{
- testName: "Show diff with custom context size",
- index: 5,
- contextSize: 77,
- ignoreWhitespace: false,
- expected: []string{"git", "-C", "/path/to/worktree", "stash", "show", "-p", "--stat", "--color=always", "--unified=77", "stash@{5}"},
+ testName: "Show diff with custom context size",
+ index: 5,
+ contextSize: 77,
+ similarityThreshold: 50,
+ ignoreWhitespace: false,
+ expected: []string{"git", "-C", "/path/to/worktree", "stash", "show", "-p", "--stat", "--color=always", "--unified=77", "--find-renames=50%", "stash@{5}"},
},
{
- testName: "Default case",
- index: 5,
- contextSize: 3,
- ignoreWhitespace: true,
- expected: []string{"git", "-C", "/path/to/worktree", "stash", "show", "-p", "--stat", "--color=always", "--unified=3", "--ignore-all-space", "stash@{5}"},
+ testName: "Show diff with custom similarity threshold",
+ index: 5,
+ contextSize: 3,
+ similarityThreshold: 33,
+ ignoreWhitespace: false,
+ expected: []string{"git", "-C", "/path/to/worktree", "stash", "show", "-p", "--stat", "--color=always", "--unified=3", "--find-renames=33%", "stash@{5}"},
+ },
+ {
+ testName: "Default case",
+ index: 5,
+ contextSize: 3,
+ similarityThreshold: 50,
+ ignoreWhitespace: true,
+ expected: []string{"git", "-C", "/path/to/worktree", "stash", "show", "-p", "--stat", "--color=always", "--unified=3", "--ignore-all-space", "--find-renames=50%", "stash@{5}"},
},
}
@@ -135,6 +147,7 @@ func TestStashStashEntryCmdObj(t *testing.T) {
appState := &config.AppState{}
appState.IgnoreWhitespaceInDiffView = s.ignoreWhitespace
appState.DiffContextSize = s.contextSize
+ appState.RenameSimilarityThreshold = s.similarityThreshold
repoPaths := RepoPaths{
worktreePath: "/path/to/worktree",
}
diff --git a/pkg/commands/git_commands/working_tree.go b/pkg/commands/git_commands/working_tree.go
index 7639dbad8..2364f2a68 100644
--- a/pkg/commands/git_commands/working_tree.go
+++ b/pkg/commands/git_commands/working_tree.go
@@ -263,6 +263,7 @@ func (self *WorkingTreeCommands) WorktreeFileDiffCmdObj(node models.IFile, plain
Arg(fmt.Sprintf("--unified=%d", contextSize)).
Arg(fmt.Sprintf("--color=%s", colorArg)).
ArgIf(!plain && self.AppState.IgnoreWhitespaceInDiffView, "--ignore-all-space").
+ Arg(fmt.Sprintf("--find-renames=%d%%", self.AppState.RenameSimilarityThreshold)).
ArgIf(cached, "--cached").
ArgIf(noIndex, "--no-index").
Arg("--").
diff --git a/pkg/commands/git_commands/working_tree_test.go b/pkg/commands/git_commands/working_tree_test.go
index cc0ad55f5..a4270e732 100644
--- a/pkg/commands/git_commands/working_tree_test.go
+++ b/pkg/commands/git_commands/working_tree_test.go
@@ -205,13 +205,14 @@ func TestWorkingTreeDiscardAllFileChanges(t *testing.T) {
func TestWorkingTreeDiff(t *testing.T) {
type scenario struct {
- testName string
- file *models.File
- plain bool
- cached bool
- ignoreWhitespace bool
- contextSize int
- runner *oscommands.FakeCmdObjRunner
+ testName string
+ file *models.File
+ plain bool
+ cached bool
+ ignoreWhitespace bool
+ contextSize int
+ similarityThreshold int
+ runner *oscommands.FakeCmdObjRunner
}
const expectedResult = "pretend this is an actual git diff"
@@ -224,12 +225,13 @@ func TestWorkingTreeDiff(t *testing.T) {
HasStagedChanges: false,
Tracked: true,
},
- plain: false,
- cached: false,
- ignoreWhitespace: false,
- contextSize: 3,
+ plain: false,
+ cached: false,
+ ignoreWhitespace: false,
+ contextSize: 3,
+ similarityThreshold: 50,
runner: oscommands.NewFakeRunner(t).
- ExpectGitArgs([]string{"-C", "/path/to/worktree", "diff", "--no-ext-diff", "--submodule", "--unified=3", "--color=always", "--", "test.txt"}, expectedResult, nil),
+ ExpectGitArgs([]string{"-C", "/path/to/worktree", "diff", "--no-ext-diff", "--submodule", "--unified=3", "--color=always", "--find-renames=50%", "--", "test.txt"}, expectedResult, nil),
},
{
testName: "cached",
@@ -238,12 +240,13 @@ func TestWorkingTreeDiff(t *testing.T) {
HasStagedChanges: false,
Tracked: true,
},
- plain: false,
- cached: true,
- ignoreWhitespace: false,
- contextSize: 3,
+ plain: false,
+ cached: true,
+ ignoreWhitespace: false,
+ contextSize: 3,
+ similarityThreshold: 50,
runner: oscommands.NewFakeRunner(t).
- ExpectGitArgs([]string{"-C", "/path/to/worktree", "diff", "--no-ext-diff", "--submodule", "--unified=3", "--color=always", "--cached", "--", "test.txt"}, expectedResult, nil),
+ ExpectGitArgs([]string{"-C", "/path/to/worktree", "diff", "--no-ext-diff", "--submodule", "--unified=3", "--color=always", "--find-renames=50%", "--cached", "--", "test.txt"}, expectedResult, nil),
},
{
testName: "plain",
@@ -252,12 +255,13 @@ func TestWorkingTreeDiff(t *testing.T) {
HasStagedChanges: false,
Tracked: true,
},
- plain: true,
- cached: false,
- ignoreWhitespace: false,
- contextSize: 3,
+ plain: true,
+ cached: false,
+ ignoreWhitespace: false,
+ contextSize: 3,
+ similarityThreshold: 50,
runner: oscommands.NewFakeRunner(t).
- ExpectGitArgs([]string{"-C", "/path/to/worktree", "diff", "--no-ext-diff", "--submodule", "--unified=3", "--color=never", "--", "test.txt"}, expectedResult, nil),
+ ExpectGitArgs([]string{"-C", "/path/to/worktree", "diff", "--no-ext-diff", "--submodule", "--unified=3", "--color=never", "--find-renames=50%", "--", "test.txt"}, expectedResult, nil),
},
{
testName: "File not tracked and file has no staged changes",
@@ -266,12 +270,13 @@ func TestWorkingTreeDiff(t *testing.T) {
HasStagedChanges: false,
Tracked: false,
},
- plain: false,
- cached: false,
- ignoreWhitespace: false,
- contextSize: 3,
+ plain: false,
+ cached: false,
+ ignoreWhitespace: false,
+ contextSize: 3,
+ similarityThreshold: 50,
runner: oscommands.NewFakeRunner(t).
- ExpectGitArgs([]string{"-C", "/path/to/worktree", "diff", "--no-ext-diff", "--submodule", "--unified=3", "--color=always", "--no-index", "--", "/dev/null", "test.txt"}, expectedResult, nil),
+ ExpectGitArgs([]string{"-C", "/path/to/worktree", "diff", "--no-ext-diff", "--submodule", "--unified=3", "--color=always", "--find-renames=50%", "--no-index", "--", "/dev/null", "test.txt"}, expectedResult, nil),
},
{
testName: "Default case (ignore whitespace)",
@@ -280,12 +285,13 @@ func TestWorkingTreeDiff(t *testing.T) {
HasStagedChanges: false,
Tracked: true,
},
- plain: false,
- cached: false,
- ignoreWhitespace: true,
- contextSize: 3,
+ plain: false,
+ cached: false,
+ ignoreWhitespace: true,
+ contextSize: 3,
+ similarityThreshold: 50,
runner: oscommands.NewFakeRunner(t).
- ExpectGitArgs([]string{"-C", "/path/to/worktree", "diff", "--no-ext-diff", "--submodule", "--unified=3", "--color=always", "--ignore-all-space", "--", "test.txt"}, expectedResult, nil),
+ ExpectGitArgs([]string{"-C", "/path/to/worktree", "diff", "--no-ext-diff", "--submodule", "--unified=3", "--color=always", "--ignore-all-space", "--find-renames=50%", "--", "test.txt"}, expectedResult, nil),
},
{
testName: "Show diff with custom context size",
@@ -294,12 +300,28 @@ func TestWorkingTreeDiff(t *testing.T) {
HasStagedChanges: false,
Tracked: true,
},
- plain: false,
- cached: false,
- ignoreWhitespace: false,
- contextSize: 17,
+ plain: false,
+ cached: false,
+ ignoreWhitespace: false,
+ contextSize: 17,
+ similarityThreshold: 50,
runner: oscommands.NewFakeRunner(t).
- ExpectGitArgs([]string{"-C", "/path/to/worktree", "diff", "--no-ext-diff", "--submodule", "--unified=17", "--color=always", "--", "test.txt"}, expectedResult, nil),
+ ExpectGitArgs([]string{"-C", "/path/to/worktree", "diff", "--no-ext-diff", "--submodule", "--unified=17", "--color=always", "--find-renames=50%", "--", "test.txt"}, expectedResult, nil),
+ },
+ {
+ testName: "Show diff with custom similarity threshold",
+ file: &models.File{
+ Name: "test.txt",
+ HasStagedChanges: false,
+ Tracked: true,
+ },
+ plain: false,
+ cached: false,
+ ignoreWhitespace: false,
+ contextSize: 3,
+ similarityThreshold: 33,
+ runner: oscommands.NewFakeRunner(t).
+ ExpectGitArgs([]string{"-C", "/path/to/worktree", "diff", "--no-ext-diff", "--submodule", "--unified=3", "--color=always", "--find-renames=33%", "--", "test.txt"}, expectedResult, nil),
},
}
@@ -309,6 +331,7 @@ func TestWorkingTreeDiff(t *testing.T) {
appState := &config.AppState{}
appState.IgnoreWhitespaceInDiffView = s.ignoreWhitespace
appState.DiffContextSize = s.contextSize
+ appState.RenameSimilarityThreshold = s.similarityThreshold
repoPaths := RepoPaths{
worktreePath: "/path/to/worktree",
}
diff --git a/pkg/config/app_config.go b/pkg/config/app_config.go
index 97f32688e..19febf9a6 100644
--- a/pkg/config/app_config.go
+++ b/pkg/config/app_config.go
@@ -370,6 +370,7 @@ type AppState struct {
HideCommandLog bool
IgnoreWhitespaceInDiffView bool
DiffContextSize int
+ RenameSimilarityThreshold int
LocalBranchSortOrder string
RemoteBranchSortOrder string
@@ -385,15 +386,16 @@ type AppState struct {
func getDefaultAppState() *AppState {
return &AppState{
- LastUpdateCheck: 0,
- RecentRepos: []string{},
- StartupPopupVersion: 0,
- LastVersion: "",
- DiffContextSize: 3,
- LocalBranchSortOrder: "recency",
- RemoteBranchSortOrder: "alphabetical",
- GitLogOrder: "", // should be "topo-order" eventually
- GitLogShowGraph: "", // should be "always" eventually
+ LastUpdateCheck: 0,
+ RecentRepos: []string{},
+ StartupPopupVersion: 0,
+ LastVersion: "",
+ DiffContextSize: 3,
+ RenameSimilarityThreshold: 50,
+ LocalBranchSortOrder: "recency",
+ RemoteBranchSortOrder: "alphabetical",
+ GitLogOrder: "", // should be "topo-order" eventually
+ GitLogShowGraph: "", // should be "always" eventually
}
}
diff --git a/pkg/config/user_config.go b/pkg/config/user_config.go
index fbf513ea6..d08e4fda4 100644
--- a/pkg/config/user_config.go
+++ b/pkg/config/user_config.go
@@ -341,73 +341,75 @@ type KeybindingConfig struct {
// damn looks like we have some inconsistencies here with -alt and -alt1
type KeybindingUniversalConfig struct {
- Quit string `yaml:"quit"`
- QuitAlt1 string `yaml:"quit-alt1"`
- Return string `yaml:"return"`
- QuitWithoutChangingDirectory string `yaml:"quitWithoutChangingDirectory"`
- TogglePanel string `yaml:"togglePanel"`
- PrevItem string `yaml:"prevItem"`
- NextItem string `yaml:"nextItem"`
- PrevItemAlt string `yaml:"prevItem-alt"`
- NextItemAlt string `yaml:"nextItem-alt"`
- PrevPage string `yaml:"prevPage"`
- NextPage string `yaml:"nextPage"`
- ScrollLeft string `yaml:"scrollLeft"`
- ScrollRight string `yaml:"scrollRight"`
- GotoTop string `yaml:"gotoTop"`
- GotoBottom string `yaml:"gotoBottom"`
- ToggleRangeSelect string `yaml:"toggleRangeSelect"`
- RangeSelectDown string `yaml:"rangeSelectDown"`
- RangeSelectUp string `yaml:"rangeSelectUp"`
- PrevBlock string `yaml:"prevBlock"`
- NextBlock string `yaml:"nextBlock"`
- PrevBlockAlt string `yaml:"prevBlock-alt"`
- NextBlockAlt string `yaml:"nextBlock-alt"`
- NextBlockAlt2 string `yaml:"nextBlock-alt2"`
- PrevBlockAlt2 string `yaml:"prevBlock-alt2"`
- JumpToBlock []string `yaml:"jumpToBlock"`
- NextMatch string `yaml:"nextMatch"`
- PrevMatch string `yaml:"prevMatch"`
- StartSearch string `yaml:"startSearch"`
- OptionMenu string `yaml:"optionMenu"`
- OptionMenuAlt1 string `yaml:"optionMenu-alt1"`
- Select string `yaml:"select"`
- GoInto string `yaml:"goInto"`
- Confirm string `yaml:"confirm"`
- ConfirmInEditor string `yaml:"confirmInEditor"`
- Remove string `yaml:"remove"`
- New string `yaml:"new"`
- Edit string `yaml:"edit"`
- OpenFile string `yaml:"openFile"`
- ScrollUpMain string `yaml:"scrollUpMain"`
- ScrollDownMain string `yaml:"scrollDownMain"`
- ScrollUpMainAlt1 string `yaml:"scrollUpMain-alt1"`
- ScrollDownMainAlt1 string `yaml:"scrollDownMain-alt1"`
- ScrollUpMainAlt2 string `yaml:"scrollUpMain-alt2"`
- ScrollDownMainAlt2 string `yaml:"scrollDownMain-alt2"`
- ExecuteCustomCommand string `yaml:"executeCustomCommand"`
- CreateRebaseOptionsMenu string `yaml:"createRebaseOptionsMenu"`
- Push string `yaml:"pushFiles"` // 'Files' appended for legacy reasons
- Pull string `yaml:"pullFiles"` // 'Files' appended for legacy reasons
- Refresh string `yaml:"refresh"`
- CreatePatchOptionsMenu string `yaml:"createPatchOptionsMenu"`
- NextTab string `yaml:"nextTab"`
- PrevTab string `yaml:"prevTab"`
- NextScreenMode string `yaml:"nextScreenMode"`
- PrevScreenMode string `yaml:"prevScreenMode"`
- Undo string `yaml:"undo"`
- Redo string `yaml:"redo"`
- FilteringMenu string `yaml:"filteringMenu"`
- DiffingMenu string `yaml:"diffingMenu"`
- DiffingMenuAlt string `yaml:"diffingMenu-alt"`
- CopyToClipboard string `yaml:"copyToClipboard"`
- OpenRecentRepos string `yaml:"openRecentRepos"`
- SubmitEditorText string `yaml:"submitEditorText"`
- ExtrasMenu string `yaml:"extrasMenu"`
- ToggleWhitespaceInDiffView string `yaml:"toggleWhitespaceInDiffView"`
- IncreaseContextInDiffView string `yaml:"increaseContextInDiffView"`
- DecreaseContextInDiffView string `yaml:"decreaseContextInDiffView"`
- OpenDiffTool string `yaml:"openDiffTool"`
+ Quit string `yaml:"quit"`
+ QuitAlt1 string `yaml:"quit-alt1"`
+ Return string `yaml:"return"`
+ QuitWithoutChangingDirectory string `yaml:"quitWithoutChangingDirectory"`
+ TogglePanel string `yaml:"togglePanel"`
+ PrevItem string `yaml:"prevItem"`
+ NextItem string `yaml:"nextItem"`
+ PrevItemAlt string `yaml:"prevItem-alt"`
+ NextItemAlt string `yaml:"nextItem-alt"`
+ PrevPage string `yaml:"prevPage"`
+ NextPage string `yaml:"nextPage"`
+ ScrollLeft string `yaml:"scrollLeft"`
+ ScrollRight string `yaml:"scrollRight"`
+ GotoTop string `yaml:"gotoTop"`
+ GotoBottom string `yaml:"gotoBottom"`
+ ToggleRangeSelect string `yaml:"toggleRangeSelect"`
+ RangeSelectDown string `yaml:"rangeSelectDown"`
+ RangeSelectUp string `yaml:"rangeSelectUp"`
+ PrevBlock string `yaml:"prevBlock"`
+ NextBlock string `yaml:"nextBlock"`
+ PrevBlockAlt string `yaml:"prevBlock-alt"`
+ NextBlockAlt string `yaml:"nextBlock-alt"`
+ NextBlockAlt2 string `yaml:"nextBlock-alt2"`
+ PrevBlockAlt2 string `yaml:"prevBlock-alt2"`
+ JumpToBlock []string `yaml:"jumpToBlock"`
+ NextMatch string `yaml:"nextMatch"`
+ PrevMatch string `yaml:"prevMatch"`
+ StartSearch string `yaml:"startSearch"`
+ OptionMenu string `yaml:"optionMenu"`
+ OptionMenuAlt1 string `yaml:"optionMenu-alt1"`
+ Select string `yaml:"select"`
+ GoInto string `yaml:"goInto"`
+ Confirm string `yaml:"confirm"`
+ ConfirmInEditor string `yaml:"confirmInEditor"`
+ Remove string `yaml:"remove"`
+ New string `yaml:"new"`
+ Edit string `yaml:"edit"`
+ OpenFile string `yaml:"openFile"`
+ ScrollUpMain string `yaml:"scrollUpMain"`
+ ScrollDownMain string `yaml:"scrollDownMain"`
+ ScrollUpMainAlt1 string `yaml:"scrollUpMain-alt1"`
+ ScrollDownMainAlt1 string `yaml:"scrollDownMain-alt1"`
+ ScrollUpMainAlt2 string `yaml:"scrollUpMain-alt2"`
+ ScrollDownMainAlt2 string `yaml:"scrollDownMain-alt2"`
+ ExecuteCustomCommand string `yaml:"executeCustomCommand"`
+ CreateRebaseOptionsMenu string `yaml:"createRebaseOptionsMenu"`
+ Push string `yaml:"pushFiles"` // 'Files' appended for legacy reasons
+ Pull string `yaml:"pullFiles"` // 'Files' appended for legacy reasons
+ Refresh string `yaml:"refresh"`
+ CreatePatchOptionsMenu string `yaml:"createPatchOptionsMenu"`
+ NextTab string `yaml:"nextTab"`
+ PrevTab string `yaml:"prevTab"`
+ NextScreenMode string `yaml:"nextScreenMode"`
+ PrevScreenMode string `yaml:"prevScreenMode"`
+ Undo string `yaml:"undo"`
+ Redo string `yaml:"redo"`
+ FilteringMenu string `yaml:"filteringMenu"`
+ DiffingMenu string `yaml:"diffingMenu"`
+ DiffingMenuAlt string `yaml:"diffingMenu-alt"`
+ CopyToClipboard string `yaml:"copyToClipboard"`
+ OpenRecentRepos string `yaml:"openRecentRepos"`
+ SubmitEditorText string `yaml:"submitEditorText"`
+ ExtrasMenu string `yaml:"extrasMenu"`
+ ToggleWhitespaceInDiffView string `yaml:"toggleWhitespaceInDiffView"`
+ IncreaseContextInDiffView string `yaml:"increaseContextInDiffView"`
+ DecreaseContextInDiffView string `yaml:"decreaseContextInDiffView"`
+ IncreaseRenameSimilarityThreshold string `yaml:"increaseRenameSimilarityThreshold"`
+ DecreaseRenameSimilarityThreshold string `yaml:"decreaseRenameSimilarityThreshold"`
+ OpenDiffTool string `yaml:"openDiffTool"`
}
type KeybindingStatusConfig struct {
@@ -777,73 +779,75 @@ func GetDefaultConfig() *UserConfig {
PromptToReturnFromSubprocess: true,
Keybinding: KeybindingConfig{
Universal: KeybindingUniversalConfig{
- Quit: "q",
- QuitAlt1: "",
- Return: "",
- QuitWithoutChangingDirectory: "Q",
- TogglePanel: "",
- PrevItem: "",
- NextItem: "",
- PrevItemAlt: "k",
- NextItemAlt: "j",
- PrevPage: ",",
- NextPage: ".",
- ScrollLeft: "H",
- ScrollRight: "L",
- GotoTop: "<",
- GotoBottom: ">",
- ToggleRangeSelect: "v",
- RangeSelectDown: "",
- RangeSelectUp: "",
- PrevBlock: "",
- NextBlock: "",
- PrevBlockAlt: "h",
- NextBlockAlt: "l",
- PrevBlockAlt2: "",
- NextBlockAlt2: "",
- JumpToBlock: []string{"1", "2", "3", "4", "5"},
- NextMatch: "n",
- PrevMatch: "N",
- StartSearch: "/",
- OptionMenu: "",
- OptionMenuAlt1: "?",
- Select: "",
- GoInto: "",
- Confirm: "",
- ConfirmInEditor: "",
- Remove: "d",
- New: "n",
- Edit: "e",
- OpenFile: "o",
- OpenRecentRepos: "",
- ScrollUpMain: "",
- ScrollDownMain: "",
- ScrollUpMainAlt1: "K",
- ScrollDownMainAlt1: "J",
- ScrollUpMainAlt2: "",
- ScrollDownMainAlt2: "",
- ExecuteCustomCommand: ":",
- CreateRebaseOptionsMenu: "m",
- Push: "P",
- Pull: "p",
- Refresh: "R",
- CreatePatchOptionsMenu: "",
- NextTab: "]",
- PrevTab: "[",
- NextScreenMode: "+",
- PrevScreenMode: "_",
- Undo: "z",
- Redo: "",
- FilteringMenu: "",
- DiffingMenu: "W",
- DiffingMenuAlt: "",
- CopyToClipboard: "",
- SubmitEditorText: "",
- ExtrasMenu: "@",
- ToggleWhitespaceInDiffView: "",
- IncreaseContextInDiffView: "}",
- DecreaseContextInDiffView: "{",
- OpenDiffTool: "",
+ Quit: "q",
+ QuitAlt1: "",
+ Return: "",
+ QuitWithoutChangingDirectory: "Q",
+ TogglePanel: "",
+ PrevItem: "",
+ NextItem: "",
+ PrevItemAlt: "k",
+ NextItemAlt: "j",
+ PrevPage: ",",
+ NextPage: ".",
+ ScrollLeft: "H",
+ ScrollRight: "L",
+ GotoTop: "<",
+ GotoBottom: ">",
+ ToggleRangeSelect: "v",
+ RangeSelectDown: "",
+ RangeSelectUp: "",
+ PrevBlock: "",
+ NextBlock: "",
+ PrevBlockAlt: "h",
+ NextBlockAlt: "l",
+ PrevBlockAlt2: "",
+ NextBlockAlt2: "",
+ JumpToBlock: []string{"1", "2", "3", "4", "5"},
+ NextMatch: "n",
+ PrevMatch: "N",
+ StartSearch: "/",
+ OptionMenu: "",
+ OptionMenuAlt1: "?",
+ Select: "",
+ GoInto: "",
+ Confirm: "",
+ ConfirmInEditor: "",
+ Remove: "d",
+ New: "n",
+ Edit: "e",
+ OpenFile: "o",
+ OpenRecentRepos: "",
+ ScrollUpMain: "",
+ ScrollDownMain: "",
+ ScrollUpMainAlt1: "K",
+ ScrollDownMainAlt1: "J",
+ ScrollUpMainAlt2: "",
+ ScrollDownMainAlt2: "",
+ ExecuteCustomCommand: ":",
+ CreateRebaseOptionsMenu: "m",
+ Push: "P",
+ Pull: "p",
+ Refresh: "R",
+ CreatePatchOptionsMenu: "",
+ NextTab: "]",
+ PrevTab: "[",
+ NextScreenMode: "+",
+ PrevScreenMode: "_",
+ Undo: "z",
+ Redo: "",
+ FilteringMenu: "",
+ DiffingMenu: "W",
+ DiffingMenuAlt: "",
+ CopyToClipboard: "",
+ SubmitEditorText: "",
+ ExtrasMenu: "@",
+ ToggleWhitespaceInDiffView: "",
+ IncreaseContextInDiffView: "}",
+ DecreaseContextInDiffView: "{",
+ IncreaseRenameSimilarityThreshold: ")",
+ DecreaseRenameSimilarityThreshold: "(",
+ OpenDiffTool: "",
},
Status: KeybindingStatusConfig{
CheckForUpdate: "u",
diff --git a/pkg/gui/controllers.go b/pkg/gui/controllers.go
index ba39fef5a..277098f37 100644
--- a/pkg/gui/controllers.go
+++ b/pkg/gui/controllers.go
@@ -179,6 +179,7 @@ func (gui *Gui) resetHelpersAndControllers() {
undoController := controllers.NewUndoController(common)
globalController := controllers.NewGlobalController(common)
contextLinesController := controllers.NewContextLinesController(common)
+ renameSimilarityThresholdController := controllers.NewRenameSimilarityThresholdController(common)
verticalScrollControllerFactory := controllers.NewVerticalScrollControllerFactory(common, &gui.viewBufferManagerMap)
branchesController := controllers.NewBranchesController(common)
@@ -383,6 +384,7 @@ func (gui *Gui) resetHelpersAndControllers() {
undoController,
globalController,
contextLinesController,
+ renameSimilarityThresholdController,
jumpToSideWindowController,
syncController,
)
diff --git a/pkg/gui/controllers/rename_similarity_threshold_controller.go b/pkg/gui/controllers/rename_similarity_threshold_controller.go
new file mode 100644
index 000000000..0b154aa36
--- /dev/null
+++ b/pkg/gui/controllers/rename_similarity_threshold_controller.go
@@ -0,0 +1,100 @@
+package controllers
+
+import (
+ "fmt"
+
+ "github.com/jesseduffield/lazygit/pkg/gui/context"
+ "github.com/jesseduffield/lazygit/pkg/gui/types"
+ "github.com/samber/lo"
+)
+
+// This controller lets you change the similarity threshold for detecting renames.
+
+var CONTEXT_KEYS_SHOWING_RENAMES = []types.ContextKey{
+ context.FILES_CONTEXT_KEY,
+ context.SUB_COMMITS_CONTEXT_KEY,
+ context.LOCAL_COMMITS_CONTEXT_KEY,
+ context.STASH_CONTEXT_KEY,
+}
+
+type RenameSimilarityThresholdController struct {
+ baseController
+ c *ControllerCommon
+}
+
+var _ types.IController = &RenameSimilarityThresholdController{}
+
+func NewRenameSimilarityThresholdController(
+ common *ControllerCommon,
+) *RenameSimilarityThresholdController {
+ return &RenameSimilarityThresholdController{
+ baseController: baseController{},
+ c: common,
+ }
+}
+
+func (self *RenameSimilarityThresholdController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
+ bindings := []*types.Binding{
+ {
+ Key: opts.GetKey(opts.Config.Universal.IncreaseRenameSimilarityThreshold),
+ Handler: self.Increase,
+ Description: self.c.Tr.IncreaseRenameSimilarityThreshold,
+ Tooltip: self.c.Tr.IncreaseRenameSimilarityThresholdTooltip,
+ },
+ {
+ Key: opts.GetKey(opts.Config.Universal.DecreaseRenameSimilarityThreshold),
+ Handler: self.Decrease,
+ Description: self.c.Tr.DecreaseRenameSimilarityThreshold,
+ Tooltip: self.c.Tr.DecreaseRenameSimilarityThresholdTooltip,
+ },
+ }
+
+ return bindings
+}
+
+func (self *RenameSimilarityThresholdController) Context() types.Context {
+ return nil
+}
+
+func (self *RenameSimilarityThresholdController) Increase() error {
+ old_size := self.c.AppState.RenameSimilarityThreshold
+
+ if self.isShowingRenames() && old_size < 100 {
+ self.c.AppState.RenameSimilarityThreshold = min(100, old_size+5)
+ return self.applyChange()
+ }
+
+ return nil
+}
+
+func (self *RenameSimilarityThresholdController) Decrease() error {
+ old_size := self.c.AppState.RenameSimilarityThreshold
+
+ if self.isShowingRenames() && old_size > 5 {
+ self.c.AppState.RenameSimilarityThreshold = max(5, old_size-5)
+ return self.applyChange()
+ }
+
+ return nil
+}
+
+func (self *RenameSimilarityThresholdController) applyChange() error {
+ self.c.Toast(fmt.Sprintf(self.c.Tr.RenameSimilarityThresholdChanged, self.c.AppState.RenameSimilarityThreshold))
+ self.c.SaveAppStateAndLogError()
+
+ currentContext := self.c.CurrentStaticContext()
+ switch currentContext.GetKey() {
+ // we make an exception for our files context, because it actually need to refresh its state afterwards.
+ case context.FILES_CONTEXT_KEY:
+ return self.c.Refresh(types.RefreshOptions{Scope: []types.RefreshableView{types.FILES}})
+ default:
+ return currentContext.HandleRenderToMain()
+ }
+}
+
+func (self *RenameSimilarityThresholdController) isShowingRenames() bool {
+ return lo.Contains(
+ CONTEXT_KEYS_SHOWING_RENAMES,
+ self.c.CurrentStaticContext().GetKey(),
+ )
+}
diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go
index d4c656202..296239dde 100644
--- a/pkg/i18n/english.go
+++ b/pkg/i18n/english.go
@@ -642,163 +642,168 @@ type TranslationSet struct {
NavigationTitle string
SuggestionsCheatsheetTitle string
// Unlike the cheatsheet title above, the real suggestions title has a little message saying press tab to focus
- SuggestionsTitle string
- SuggestionsSubtitle string
- ExtrasTitle string
- PushingTagStatus string
- PullRequestURLCopiedToClipboard string
- CommitDiffCopiedToClipboard string
- CommitURLCopiedToClipboard string
- CommitMessageCopiedToClipboard string
- CommitSubjectCopiedToClipboard string
- CommitAuthorCopiedToClipboard string
- PatchCopiedToClipboard string
- CopiedToClipboard string
- ErrCannotEditDirectory string
- ErrStageDirWithInlineMergeConflicts string
- ErrRepositoryMovedOrDeleted string
- ErrWorktreeMovedOrRemoved string
- CommandLog string
- ToggleShowCommandLog string
- FocusCommandLog string
- CommandLogHeader string
- RandomTip string
- SelectParentCommitForMerge string
- ToggleWhitespaceInDiffView string
- ToggleWhitespaceInDiffViewTooltip string
- IgnoreWhitespaceDiffViewSubTitle string
- IgnoreWhitespaceNotSupportedHere string
- IncreaseContextInDiffView string
- IncreaseContextInDiffViewTooltip string
- DecreaseContextInDiffView string
- DecreaseContextInDiffViewTooltip string
- DiffContextSizeChanged string
- CreatePullRequestOptions string
- DefaultBranch string
- SelectBranch string
- CreatePullRequest string
- SelectConfigFile string
- NoConfigFileFoundErr string
- LoadingFileSuggestions string
- LoadingCommits string
- MustSpecifyOriginError string
- GitOutput string
- GitCommandFailed string
- AbortTitle string
- AbortPrompt string
- OpenLogMenu string
- OpenLogMenuTooltip string
- LogMenuTitle string
- ToggleShowGitGraphAll string
- ShowGitGraph string
- SortOrder string
- SortAlphabetical string
- SortByDate string
- SortByRecency string
- SortBasedOnReflog string
- SortCommits string
- CantChangeContextSizeError string
- OpenCommitInBrowser string
- ViewBisectOptions string
- ConfirmRevertCommit string
- RewordInEditorTitle string
- RewordInEditorPrompt string
- CheckoutPrompt string
- HardResetAutostashPrompt string
- UpstreamGone string
- NukeDescription string
- DiscardStagedChangesDescription string
- EmptyOutput string
- Patch string
- CustomPatch string
- CommitsCopied string
- CommitCopied string
- ResetPatch string
- ResetPatchTooltip string
- ApplyPatch string
- ApplyPatchTooltip string
- ApplyPatchInReverse string
- ApplyPatchInReverseTooltip string
- RemovePatchFromOriginalCommit string
- RemovePatchFromOriginalCommitTooltip string
- MovePatchOutIntoIndex string
- MovePatchOutIntoIndexTooltip string
- MovePatchIntoNewCommit string
- MovePatchIntoNewCommitTooltip string
- MovePatchToSelectedCommit string
- MovePatchToSelectedCommitTooltip string
- CopyPatchToClipboard string
- NoMatchesFor string
- MatchesFor string
- SearchKeybindings string
- SearchPrefix string
- FilterPrefix string
- ExitSearchMode string
- ExitTextFilterMode string
- Switch string
- SwitchToWorktree string
- SwitchToWorktreeTooltip string
- AlreadyCheckedOutByWorktree string
- BranchCheckedOutByWorktree string
- DetachWorktreeTooltip string
- Switching string
- RemoveWorktree string
- RemoveWorktreeTitle string
- DetachWorktree string
- DetachingWorktree string
- WorktreesTitle string
- WorktreeTitle string
- RemoveWorktreePrompt string
- ForceRemoveWorktreePrompt string
- RemovingWorktree string
- AddingWorktree string
- CantDeleteCurrentWorktree string
- AlreadyInWorktree string
- CantDeleteMainWorktree string
- NoWorktreesThisRepo string
- MissingWorktree string
- MainWorktree string
- NewWorktree string
- NewWorktreePath string
- NewWorktreeBase string
- RemoveWorktreeTooltip string
- BranchNameCannotBeBlank string
- NewBranchName string
- NewBranchNameLeaveBlank string
- ViewWorktreeOptions string
- CreateWorktreeFrom string
- CreateWorktreeFromDetached string
- LcWorktree string
- ChangingDirectoryTo string
- Name string
- Branch string
- Path string
- MarkedBaseCommitStatus string
- MarkAsBaseCommit string
- MarkAsBaseCommitTooltip string
- MarkedCommitMarker string
- PleaseGoToURL string
- NoCopiedCommits string
- DisabledMenuItemPrefix string
- QuickStartInteractiveRebase string
- QuickStartInteractiveRebaseTooltip string
- CannotQuickStartInteractiveRebase string
- ToggleRangeSelect string
- RangeSelectUp string
- RangeSelectDown string
- RangeSelectNotSupported string
- NoItemSelected string
- SelectedItemIsNotABranch string
- SelectedItemDoesNotHaveFiles string
- RangeSelectNotSupportedForSubmodules string
- OldCherryPickKeyWarning string
- CommandDoesNotSupportOpeningInEditor string
- Actions Actions
- Bisect Bisect
- Log Log
- BreakingChangesTitle string
- BreakingChangesMessage string
- BreakingChangesByVersion map[string]string
+ SuggestionsTitle string
+ SuggestionsSubtitle string
+ ExtrasTitle string
+ PushingTagStatus string
+ PullRequestURLCopiedToClipboard string
+ CommitDiffCopiedToClipboard string
+ CommitURLCopiedToClipboard string
+ CommitMessageCopiedToClipboard string
+ CommitSubjectCopiedToClipboard string
+ CommitAuthorCopiedToClipboard string
+ PatchCopiedToClipboard string
+ CopiedToClipboard string
+ ErrCannotEditDirectory string
+ ErrStageDirWithInlineMergeConflicts string
+ ErrRepositoryMovedOrDeleted string
+ ErrWorktreeMovedOrRemoved string
+ CommandLog string
+ ToggleShowCommandLog string
+ FocusCommandLog string
+ CommandLogHeader string
+ RandomTip string
+ SelectParentCommitForMerge string
+ ToggleWhitespaceInDiffView string
+ ToggleWhitespaceInDiffViewTooltip string
+ IgnoreWhitespaceDiffViewSubTitle string
+ IgnoreWhitespaceNotSupportedHere string
+ IncreaseContextInDiffView string
+ IncreaseContextInDiffViewTooltip string
+ DecreaseContextInDiffView string
+ DecreaseContextInDiffViewTooltip string
+ DiffContextSizeChanged string
+ IncreaseRenameSimilarityThreshold string
+ IncreaseRenameSimilarityThresholdTooltip string
+ DecreaseRenameSimilarityThreshold string
+ DecreaseRenameSimilarityThresholdTooltip string
+ RenameSimilarityThresholdChanged string
+ CreatePullRequestOptions string
+ DefaultBranch string
+ SelectBranch string
+ CreatePullRequest string
+ SelectConfigFile string
+ NoConfigFileFoundErr string
+ LoadingFileSuggestions string
+ LoadingCommits string
+ MustSpecifyOriginError string
+ GitOutput string
+ GitCommandFailed string
+ AbortTitle string
+ AbortPrompt string
+ OpenLogMenu string
+ OpenLogMenuTooltip string
+ LogMenuTitle string
+ ToggleShowGitGraphAll string
+ ShowGitGraph string
+ SortOrder string
+ SortAlphabetical string
+ SortByDate string
+ SortByRecency string
+ SortBasedOnReflog string
+ SortCommits string
+ CantChangeContextSizeError string
+ OpenCommitInBrowser string
+ ViewBisectOptions string
+ ConfirmRevertCommit string
+ RewordInEditorTitle string
+ RewordInEditorPrompt string
+ CheckoutPrompt string
+ HardResetAutostashPrompt string
+ UpstreamGone string
+ NukeDescription string
+ DiscardStagedChangesDescription string
+ EmptyOutput string
+ Patch string
+ CustomPatch string
+ CommitsCopied string
+ CommitCopied string
+ ResetPatch string
+ ResetPatchTooltip string
+ ApplyPatch string
+ ApplyPatchTooltip string
+ ApplyPatchInReverse string
+ ApplyPatchInReverseTooltip string
+ RemovePatchFromOriginalCommit string
+ RemovePatchFromOriginalCommitTooltip string
+ MovePatchOutIntoIndex string
+ MovePatchOutIntoIndexTooltip string
+ MovePatchIntoNewCommit string
+ MovePatchIntoNewCommitTooltip string
+ MovePatchToSelectedCommit string
+ MovePatchToSelectedCommitTooltip string
+ CopyPatchToClipboard string
+ NoMatchesFor string
+ MatchesFor string
+ SearchKeybindings string
+ SearchPrefix string
+ FilterPrefix string
+ ExitSearchMode string
+ ExitTextFilterMode string
+ Switch string
+ SwitchToWorktree string
+ SwitchToWorktreeTooltip string
+ AlreadyCheckedOutByWorktree string
+ BranchCheckedOutByWorktree string
+ DetachWorktreeTooltip string
+ Switching string
+ RemoveWorktree string
+ RemoveWorktreeTitle string
+ DetachWorktree string
+ DetachingWorktree string
+ WorktreesTitle string
+ WorktreeTitle string
+ RemoveWorktreePrompt string
+ ForceRemoveWorktreePrompt string
+ RemovingWorktree string
+ AddingWorktree string
+ CantDeleteCurrentWorktree string
+ AlreadyInWorktree string
+ CantDeleteMainWorktree string
+ NoWorktreesThisRepo string
+ MissingWorktree string
+ MainWorktree string
+ NewWorktree string
+ NewWorktreePath string
+ NewWorktreeBase string
+ RemoveWorktreeTooltip string
+ BranchNameCannotBeBlank string
+ NewBranchName string
+ NewBranchNameLeaveBlank string
+ ViewWorktreeOptions string
+ CreateWorktreeFrom string
+ CreateWorktreeFromDetached string
+ LcWorktree string
+ ChangingDirectoryTo string
+ Name string
+ Branch string
+ Path string
+ MarkedBaseCommitStatus string
+ MarkAsBaseCommit string
+ MarkAsBaseCommitTooltip string
+ MarkedCommitMarker string
+ PleaseGoToURL string
+ NoCopiedCommits string
+ DisabledMenuItemPrefix string
+ QuickStartInteractiveRebase string
+ QuickStartInteractiveRebaseTooltip string
+ CannotQuickStartInteractiveRebase string
+ ToggleRangeSelect string
+ RangeSelectUp string
+ RangeSelectDown string
+ RangeSelectNotSupported string
+ NoItemSelected string
+ SelectedItemIsNotABranch string
+ SelectedItemDoesNotHaveFiles string
+ RangeSelectNotSupportedForSubmodules string
+ OldCherryPickKeyWarning string
+ CommandDoesNotSupportOpeningInEditor string
+ Actions Actions
+ Bisect Bisect
+ Log Log
+ BreakingChangesTitle string
+ BreakingChangesMessage string
+ BreakingChangesByVersion map[string]string
}
type Bisect struct {
@@ -1554,219 +1559,224 @@ func EnglishTranslationSet() *TranslationSet {
ViewDiffingOptions: "View diffing options",
ViewDiffingOptionsTooltip: "View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction.",
// the actual view is the extras view which I intend to give more tabs in future but for now we'll only mention the command log part
- OpenCommandLogMenu: "View command log options",
- OpenCommandLogMenuTooltip: "View options for the command log e.g. show/hide the command log and focus the command log.",
- ShowingGitDiff: "Showing output for:",
- CommitDiff: "Commit diff",
- CopyCommitHashToClipboard: "Copy commit hash to clipboard",
- CommitHash: "Commit hash",
- CommitURL: "Commit URL",
- CopyCommitMessageToClipboard: "Copy commit message to clipboard",
- PasteCommitMessageFromClipboard: "Paste commit message from clipboard",
- SurePasteCommitMessage: "Pasting will overwrite the current commit message, continue?",
- CommitMessage: "Commit message",
- CommitSubject: "Commit subject",
- CommitAuthor: "Commit author",
- CopyCommitAttributeToClipboard: "Copy commit attribute to clipboard",
- CopyCommitAttributeToClipboardTooltip: "Copy commit attribute to clipboard (e.g. hash, URL, diff, message, author).",
- CopyBranchNameToClipboard: "Copy branch name to clipboard",
- CopyPathToClipboard: "Copy path to clipboard",
- CopySelectedTextToClipboard: "Copy selected text to clipboard",
- CommitPrefixPatternError: "Error in commitPrefix pattern",
- NoFilesStagedTitle: "No files staged",
- NoFilesStagedPrompt: "You have not staged any files. Commit all files?",
- BranchNotFoundTitle: "Branch not found",
- BranchNotFoundPrompt: "Branch not found. Create a new branch named",
- BranchUnknown: "Branch unknown",
- DiscardChangeTitle: "Discard change",
- DiscardChangePrompt: "Are you sure you want to discard this change (git reset)? It is irreversible.\nTo disable this dialogue set the config key of 'gui.skipDiscardChangeWarning' to true",
- CreateNewBranchFromCommit: "Create new branch off of commit",
- BuildingPatch: "Building patch",
- ViewCommits: "View commits",
- MinGitVersionError: "Git version must be at least 2.20 (i.e. from 2018 onwards). Please upgrade your git version. Alternatively raise an issue at https://github.com/jesseduffield/lazygit/issues for lazygit to be more backwards compatible.",
- RunningCustomCommandStatus: "Running custom command",
- SubmoduleStashAndReset: "Stash uncommitted submodule changes and update",
- AndResetSubmodules: "And reset submodules",
- Enter: "Enter",
- EnterSubmoduleTooltip: "Enter submodule. After entering the submodule, you can press `{{.escape}}` to escape back to the parent repo.",
- CopySubmoduleNameToClipboard: "Copy submodule name to clipboard",
- RemoveSubmodule: "Remove submodule",
- RemoveSubmodulePrompt: "Are you sure you want to remove submodule '%s' and its corresponding directory? This is irreversible.",
- RemoveSubmoduleTooltip: "Remove the selected submodule and its corresponding directory.",
- ResettingSubmoduleStatus: "Resetting submodule",
- NewSubmoduleName: "New submodule name:",
- NewSubmoduleUrl: "New submodule URL:",
- NewSubmodulePath: "New submodule path:",
- NewSubmodule: "New submodule",
- AddingSubmoduleStatus: "Adding submodule",
- UpdateSubmoduleUrl: "Update URL for submodule '%s'",
- UpdatingSubmoduleUrlStatus: "Updating URL",
- EditSubmoduleUrl: "Update submodule URL",
- InitializingSubmoduleStatus: "Initializing submodule",
- InitSubmoduleTooltip: "Initialize the selected submodule to prepare for fetching. You probably want to follow this up by invoking the 'update' action to fetch the submodule.",
- Update: "Update",
- Initialize: "Initialize",
- SubmoduleUpdateTooltip: "Update selected submodule.",
- UpdatingSubmoduleStatus: "Updating submodule",
- BulkInitSubmodules: "Bulk init submodules",
- BulkUpdateSubmodules: "Bulk update submodules",
- BulkDeinitSubmodules: "Bulk deinit submodules",
- ViewBulkSubmoduleOptions: "View bulk submodule options",
- BulkSubmoduleOptions: "Bulk submodule options",
- RunningCommand: "Running command",
- SubCommitsTitle: "Sub-commits",
- SubmodulesTitle: "Submodules",
- NavigationTitle: "List panel navigation",
- SuggestionsCheatsheetTitle: "Suggestions",
- SuggestionsTitle: "Suggestions (press %s to focus)",
- SuggestionsSubtitle: "(press %s to delete, %s to edit)",
- ExtrasTitle: "Command log",
- PushingTagStatus: "Pushing tag",
- PullRequestURLCopiedToClipboard: "Pull request URL copied to clipboard",
- CommitDiffCopiedToClipboard: "Commit diff copied to clipboard",
- CommitURLCopiedToClipboard: "Commit URL copied to clipboard",
- CommitMessageCopiedToClipboard: "Commit message copied to clipboard",
- CommitSubjectCopiedToClipboard: "Commit subject copied to clipboard",
- CommitAuthorCopiedToClipboard: "Commit author copied to clipboard",
- PatchCopiedToClipboard: "Patch copied to clipboard",
- CopiedToClipboard: "copied to clipboard",
- ErrCannotEditDirectory: "Cannot edit directories: you can only edit individual files",
- ErrStageDirWithInlineMergeConflicts: "Cannot stage/unstage directory containing files with inline merge conflicts. Please fix up the merge conflicts first",
- ErrRepositoryMovedOrDeleted: "Cannot find repo. It might have been moved or deleted ¯\\_(ツ)_/¯",
- CommandLog: "Command log",
- ErrWorktreeMovedOrRemoved: "Cannot find worktree. It might have been moved or removed ¯\\_(ツ)_/¯",
- ToggleShowCommandLog: "Toggle show/hide command log",
- FocusCommandLog: "Focus command log",
- CommandLogHeader: "You can hide/focus this panel by pressing '%s'\n",
- RandomTip: "Random tip",
- SelectParentCommitForMerge: "Select parent commit for merge",
- ToggleWhitespaceInDiffView: "Toggle whitespace",
- ToggleWhitespaceInDiffViewTooltip: "Toggle whether or not whitespace changes are shown in the diff view.",
- IgnoreWhitespaceDiffViewSubTitle: "(ignoring whitespace)",
- IgnoreWhitespaceNotSupportedHere: "Ignoring whitespace is not supported in this view",
- IncreaseContextInDiffView: "Increase diff context size",
- IncreaseContextInDiffViewTooltip: "Increase the amount of the context shown around changes in the diff view.",
- DecreaseContextInDiffView: "Decrease diff context size",
- DecreaseContextInDiffViewTooltip: "Decrease the amount of the context shown around changes in the diff view.",
- DiffContextSizeChanged: "Changed diff context size to %d",
- CreatePullRequestOptions: "View create pull request options",
- DefaultBranch: "Default branch",
- SelectBranch: "Select branch",
- SelectConfigFile: "Select config file",
- NoConfigFileFoundErr: "No config file found",
- LoadingFileSuggestions: "Loading file suggestions",
- LoadingCommits: "Loading commits",
- MustSpecifyOriginError: "Must specify a remote if specifying a branch",
- GitOutput: "Git output:",
- GitCommandFailed: "Git command failed. Check command log for details (open with %s)",
- AbortTitle: "Abort %s",
- AbortPrompt: "Are you sure you want to abort the current %s?",
- OpenLogMenu: "View log options",
- OpenLogMenuTooltip: "View options for commit log e.g. changing sort order, hiding the git graph, showing the whole git graph.",
- LogMenuTitle: "Commit Log Options",
- ToggleShowGitGraphAll: "Toggle show whole git graph (pass the `--all` flag to `git log`)",
- ShowGitGraph: "Show git graph",
- SortOrder: "Sort order",
- SortAlphabetical: "Alphabetical",
- SortByDate: "Date",
- SortByRecency: "Recency",
- SortBasedOnReflog: "(based on reflog)",
- SortCommits: "Commit sort order",
- CantChangeContextSizeError: "Cannot change context while in patch building mode because we were too lazy to support it when releasing the feature. If you really want it, please let us know!",
- OpenCommitInBrowser: "Open commit in browser",
- ViewBisectOptions: "View bisect options",
- ConfirmRevertCommit: "Are you sure you want to revert {{.selectedCommit}}?",
- RewordInEditorTitle: "Reword in editor",
- RewordInEditorPrompt: "Are you sure you want to reword this commit in your editor?",
- HardResetAutostashPrompt: "Are you sure you want to hard reset to '%s'? An auto-stash will be performed if necessary.",
- CheckoutPrompt: "Are you sure you want to checkout '%s'?",
- UpstreamGone: "(upstream gone)",
- NukeDescription: "If you want to make all the changes in the worktree go away, this is the way to do it. If there are dirty submodule changes this will stash those changes in the submodule(s).",
- DiscardStagedChangesDescription: "This will create a new stash entry containing only staged files and then drop it, so that the working tree is left with only unstaged changes",
- EmptyOutput: "",
- Patch: "Patch",
- CustomPatch: "Custom patch",
- CommitsCopied: "commits copied", // lowercase because it's used in a sentence
- CommitCopied: "commit copied", // lowercase because it's used in a sentence
- ResetPatch: "Reset patch",
- ResetPatchTooltip: "Clear the current patch.",
- ApplyPatch: "Apply patch",
- ApplyPatchTooltip: "Apply the current patch to the working tree.",
- ApplyPatchInReverse: "Apply patch in reverse",
- ApplyPatchInReverseTooltip: "Apply the current patch in reverse to the working tree.",
- RemovePatchFromOriginalCommit: "Remove patch from original commit (%s)",
- RemovePatchFromOriginalCommitTooltip: "Remove the current patch from its commit. This is achieved by starting an interactive rebase at the commit, applying the patch in reverse, and then continuing the rebase. If later commits depend on the patch, you may need to resolve conflicts.",
- MovePatchOutIntoIndex: "Move patch out into index",
- MovePatchOutIntoIndexTooltip: "Move the patch out of its commit and into the index. This is achieved by starting an interactive rebase at the commit, applying the patch in reverse, continuing the rebase to completion, and then applying the patch to the index. If later commits depend on the patch, you may need to resolve conflicts.",
- MovePatchIntoNewCommit: "Move patch into new commit",
- MovePatchIntoNewCommitTooltip: "Move the patch out of its commit and into a new commit sitting on top of the original commit. This is achieved by starting an interactive rebase at the original commit, applying the patch in reverse, then applying the patch to the index and committing it as a new commit, before continuing the rebase to completion. If later commits depend on the patch, you may need to resolve conflicts.",
- MovePatchToSelectedCommit: "Move patch to selected commit (%s)",
- MovePatchToSelectedCommitTooltip: "Move the patch out of its original commit and into the selected commit. This is achieved by starting an interactive rebase at the original commit, applying the patch in reverse, then continuing the rebase up to the selected commit, before applying the patch forward and amending the seleced commit. The rebase is then continued to completion. If commits between the source and destination commit depend on the patch, you may need to resolve conflicts.",
- CopyPatchToClipboard: "Copy patch to clipboard",
- NoMatchesFor: "No matches for '%s' %s",
- ExitSearchMode: "%s: Exit search mode",
- ExitTextFilterMode: "%s: Exit filter mode",
- MatchesFor: "matches for '%s' (%d of %d) %s", // lowercase because it's after other text
- SearchKeybindings: "%s: Next match, %s: Previous match, %s: Exit search mode",
- SearchPrefix: "Search: ",
- FilterPrefix: "Filter: ",
- WorktreesTitle: "Worktrees",
- WorktreeTitle: "Worktree",
- Switch: "Switch",
- SwitchToWorktree: "Switch to worktree",
- SwitchToWorktreeTooltip: "Switch to the selected worktree.",
- AlreadyCheckedOutByWorktree: "This branch is checked out by worktree {{.worktreeName}}. Do you want to switch to that worktree?",
- BranchCheckedOutByWorktree: "Branch {{.branchName}} is checked out by worktree {{.worktreeName}}",
- DetachWorktreeTooltip: "This will run `git checkout --detach` on the worktree so that it stops hogging the branch, but the worktree's working tree will be left alone.",
- Switching: "Switching",
- RemoveWorktree: "Remove worktree",
- RemoveWorktreeTitle: "Remove worktree",
- RemoveWorktreePrompt: "Are you sure you want to remove worktree '{{.worktreeName}}'?",
- ForceRemoveWorktreePrompt: "'{{.worktreeName}}' contains modified or untracked files (to be honest, it could contain both). Are you sure you want to remove it?",
- RemovingWorktree: "Deleting worktree",
- DetachWorktree: "Detach worktree",
- DetachingWorktree: "Detaching worktree",
- AddingWorktree: "Adding worktree",
- CantDeleteCurrentWorktree: "You cannot remove the current worktree!",
- AlreadyInWorktree: "You are already in the selected worktree",
- CantDeleteMainWorktree: "You cannot remove the main worktree!",
- NoWorktreesThisRepo: "No worktrees",
- MissingWorktree: "(missing)",
- MainWorktree: "(main)",
- NewWorktree: "New worktree",
- NewWorktreePath: "New worktree path",
- NewWorktreeBase: "New worktree base ref",
- RemoveWorktreeTooltip: "Remove the selected worktree. This will both delete the worktree's directory, as well as metadata about the worktree in the .git directory.",
- BranchNameCannotBeBlank: "Branch name cannot be blank",
- NewBranchName: "New branch name",
- NewBranchNameLeaveBlank: "New branch name (leave blank to checkout {{.default}})",
- ViewWorktreeOptions: "View worktree options",
- CreateWorktreeFrom: "Create worktree from {{.ref}}",
- CreateWorktreeFromDetached: "Create worktree from {{.ref}} (detached)",
- LcWorktree: "worktree",
- ChangingDirectoryTo: "Changing directory to {{.path}}",
- Name: "Name",
- Branch: "Branch",
- Path: "Path",
- MarkedBaseCommitStatus: "Marked a base commit for rebase",
- MarkAsBaseCommit: "Mark as base commit for rebase",
- MarkAsBaseCommitTooltip: "Select a base commit for the next rebase. When you rebase onto a branch, only commits above the base commit will be brought across. This uses the `git rebase --onto` command.",
- MarkedCommitMarker: "↑↑↑ Will rebase from here ↑↑↑",
- PleaseGoToURL: "Please go to {{.url}}",
- DisabledMenuItemPrefix: "Disabled: ",
- NoCopiedCommits: "No copied commits",
- QuickStartInteractiveRebase: "Start interactive rebase",
- QuickStartInteractiveRebaseTooltip: "Start an interactive rebase for the commits on your branch. This will include all commits from the HEAD commit down to the first merge commit or main branch commit.\nIf you would instead like to start an interactive rebase from the selected commit, press `{{.editKey}}`.",
- CannotQuickStartInteractiveRebase: "Cannot start interactive rebase: the HEAD commit is a merge commit or is present on the main branch, so there is no appropriate base commit to start the rebase from. You can start an interactive rebase from a specific commit by selecting the commit and pressing `{{.editKey}}`.",
- RangeSelectUp: "Range select up",
- RangeSelectDown: "Range select down",
- RangeSelectNotSupported: "Action does not support range selection, please select a single item",
- NoItemSelected: "No item selected",
- SelectedItemIsNotABranch: "Selected item is not a branch",
- SelectedItemDoesNotHaveFiles: "Selected item does not have files to view",
- RangeSelectNotSupportedForSubmodules: "Range select not supported for submodules",
- OldCherryPickKeyWarning: "The 'c' key is no longer the default key for copying commits to cherry pick. Please use `{{.copy}}` instead (and `{{.paste}}` to paste). The reason for this change is that the 'v' key for selecting a range of lines when staging is now also used for selecting a range of lines in any list view, meaning that we needed to find a new key for pasting commits, and if we're going to now use `{{.paste}}` for pasting commits, we may as well use `{{.copy}}` for copying them. If you want to configure the keybindings to get the old behaviour, set the following in your config:\n\nkeybinding:\n universal:\n toggleRangeSelect: \n commits:\n cherryPickCopy: 'c'\n pasteCommits: 'v'",
- CommandDoesNotSupportOpeningInEditor: "This command doesn't support switching to the editor",
+ OpenCommandLogMenu: "View command log options",
+ OpenCommandLogMenuTooltip: "View options for the command log e.g. show/hide the command log and focus the command log.",
+ ShowingGitDiff: "Showing output for:",
+ CommitDiff: "Commit diff",
+ CopyCommitHashToClipboard: "Copy commit hash to clipboard",
+ CommitHash: "Commit hash",
+ CommitURL: "Commit URL",
+ CopyCommitMessageToClipboard: "Copy commit message to clipboard",
+ PasteCommitMessageFromClipboard: "Paste commit message from clipboard",
+ SurePasteCommitMessage: "Pasting will overwrite the current commit message, continue?",
+ CommitMessage: "Commit message",
+ CommitSubject: "Commit subject",
+ CommitAuthor: "Commit author",
+ CopyCommitAttributeToClipboard: "Copy commit attribute to clipboard",
+ CopyCommitAttributeToClipboardTooltip: "Copy commit attribute to clipboard (e.g. hash, URL, diff, message, author).",
+ CopyBranchNameToClipboard: "Copy branch name to clipboard",
+ CopyPathToClipboard: "Copy path to clipboard",
+ CopySelectedTextToClipboard: "Copy selected text to clipboard",
+ CommitPrefixPatternError: "Error in commitPrefix pattern",
+ NoFilesStagedTitle: "No files staged",
+ NoFilesStagedPrompt: "You have not staged any files. Commit all files?",
+ BranchNotFoundTitle: "Branch not found",
+ BranchNotFoundPrompt: "Branch not found. Create a new branch named",
+ BranchUnknown: "Branch unknown",
+ DiscardChangeTitle: "Discard change",
+ DiscardChangePrompt: "Are you sure you want to discard this change (git reset)? It is irreversible.\nTo disable this dialogue set the config key of 'gui.skipDiscardChangeWarning' to true",
+ CreateNewBranchFromCommit: "Create new branch off of commit",
+ BuildingPatch: "Building patch",
+ ViewCommits: "View commits",
+ MinGitVersionError: "Git version must be at least 2.20 (i.e. from 2018 onwards). Please upgrade your git version. Alternatively raise an issue at https://github.com/jesseduffield/lazygit/issues for lazygit to be more backwards compatible.",
+ RunningCustomCommandStatus: "Running custom command",
+ SubmoduleStashAndReset: "Stash uncommitted submodule changes and update",
+ AndResetSubmodules: "And reset submodules",
+ Enter: "Enter",
+ EnterSubmoduleTooltip: "Enter submodule. After entering the submodule, you can press `{{.escape}}` to escape back to the parent repo.",
+ CopySubmoduleNameToClipboard: "Copy submodule name to clipboard",
+ RemoveSubmodule: "Remove submodule",
+ RemoveSubmodulePrompt: "Are you sure you want to remove submodule '%s' and its corresponding directory? This is irreversible.",
+ RemoveSubmoduleTooltip: "Remove the selected submodule and its corresponding directory.",
+ ResettingSubmoduleStatus: "Resetting submodule",
+ NewSubmoduleName: "New submodule name:",
+ NewSubmoduleUrl: "New submodule URL:",
+ NewSubmodulePath: "New submodule path:",
+ NewSubmodule: "New submodule",
+ AddingSubmoduleStatus: "Adding submodule",
+ UpdateSubmoduleUrl: "Update URL for submodule '%s'",
+ UpdatingSubmoduleUrlStatus: "Updating URL",
+ EditSubmoduleUrl: "Update submodule URL",
+ InitializingSubmoduleStatus: "Initializing submodule",
+ InitSubmoduleTooltip: "Initialize the selected submodule to prepare for fetching. You probably want to follow this up by invoking the 'update' action to fetch the submodule.",
+ Update: "Update",
+ Initialize: "Initialize",
+ SubmoduleUpdateTooltip: "Update selected submodule.",
+ UpdatingSubmoduleStatus: "Updating submodule",
+ BulkInitSubmodules: "Bulk init submodules",
+ BulkUpdateSubmodules: "Bulk update submodules",
+ BulkDeinitSubmodules: "Bulk deinit submodules",
+ ViewBulkSubmoduleOptions: "View bulk submodule options",
+ BulkSubmoduleOptions: "Bulk submodule options",
+ RunningCommand: "Running command",
+ SubCommitsTitle: "Sub-commits",
+ SubmodulesTitle: "Submodules",
+ NavigationTitle: "List panel navigation",
+ SuggestionsCheatsheetTitle: "Suggestions",
+ SuggestionsTitle: "Suggestions (press %s to focus)",
+ SuggestionsSubtitle: "(press %s to delete, %s to edit)",
+ ExtrasTitle: "Command log",
+ PushingTagStatus: "Pushing tag",
+ PullRequestURLCopiedToClipboard: "Pull request URL copied to clipboard",
+ CommitDiffCopiedToClipboard: "Commit diff copied to clipboard",
+ CommitURLCopiedToClipboard: "Commit URL copied to clipboard",
+ CommitMessageCopiedToClipboard: "Commit message copied to clipboard",
+ CommitSubjectCopiedToClipboard: "Commit subject copied to clipboard",
+ CommitAuthorCopiedToClipboard: "Commit author copied to clipboard",
+ PatchCopiedToClipboard: "Patch copied to clipboard",
+ CopiedToClipboard: "copied to clipboard",
+ ErrCannotEditDirectory: "Cannot edit directories: you can only edit individual files",
+ ErrStageDirWithInlineMergeConflicts: "Cannot stage/unstage directory containing files with inline merge conflicts. Please fix up the merge conflicts first",
+ ErrRepositoryMovedOrDeleted: "Cannot find repo. It might have been moved or deleted ¯\\_(ツ)_/¯",
+ CommandLog: "Command log",
+ ErrWorktreeMovedOrRemoved: "Cannot find worktree. It might have been moved or removed ¯\\_(ツ)_/¯",
+ ToggleShowCommandLog: "Toggle show/hide command log",
+ FocusCommandLog: "Focus command log",
+ CommandLogHeader: "You can hide/focus this panel by pressing '%s'\n",
+ RandomTip: "Random tip",
+ SelectParentCommitForMerge: "Select parent commit for merge",
+ ToggleWhitespaceInDiffView: "Toggle whitespace",
+ ToggleWhitespaceInDiffViewTooltip: "Toggle whether or not whitespace changes are shown in the diff view.",
+ IgnoreWhitespaceDiffViewSubTitle: "(ignoring whitespace)",
+ IgnoreWhitespaceNotSupportedHere: "Ignoring whitespace is not supported in this view",
+ IncreaseContextInDiffView: "Increase diff context size",
+ IncreaseContextInDiffViewTooltip: "Increase the amount of the context shown around changes in the diff view.",
+ DecreaseContextInDiffView: "Decrease diff context size",
+ DecreaseContextInDiffViewTooltip: "Decrease the amount of the context shown around changes in the diff view.",
+ DiffContextSizeChanged: "Changed diff context size to %d",
+ IncreaseRenameSimilarityThresholdTooltip: "Increase the similarity threshold for a deletion and addition pair to be treated as a rename.",
+ IncreaseRenameSimilarityThreshold: "Increase rename similarity threshold",
+ DecreaseRenameSimilarityThresholdTooltip: "Decrease the similarity threshold for a deletion and addition pair to be treated as a rename.",
+ DecreaseRenameSimilarityThreshold: "Decrease rename similarity threshold",
+ RenameSimilarityThresholdChanged: "Changed rename similarity threshold to %d%%",
+ CreatePullRequestOptions: "View create pull request options",
+ DefaultBranch: "Default branch",
+ SelectBranch: "Select branch",
+ SelectConfigFile: "Select config file",
+ NoConfigFileFoundErr: "No config file found",
+ LoadingFileSuggestions: "Loading file suggestions",
+ LoadingCommits: "Loading commits",
+ MustSpecifyOriginError: "Must specify a remote if specifying a branch",
+ GitOutput: "Git output:",
+ GitCommandFailed: "Git command failed. Check command log for details (open with %s)",
+ AbortTitle: "Abort %s",
+ AbortPrompt: "Are you sure you want to abort the current %s?",
+ OpenLogMenu: "View log options",
+ OpenLogMenuTooltip: "View options for commit log e.g. changing sort order, hiding the git graph, showing the whole git graph.",
+ LogMenuTitle: "Commit Log Options",
+ ToggleShowGitGraphAll: "Toggle show whole git graph (pass the `--all` flag to `git log`)",
+ ShowGitGraph: "Show git graph",
+ SortOrder: "Sort order",
+ SortAlphabetical: "Alphabetical",
+ SortByDate: "Date",
+ SortByRecency: "Recency",
+ SortBasedOnReflog: "(based on reflog)",
+ SortCommits: "Commit sort order",
+ CantChangeContextSizeError: "Cannot change context while in patch building mode because we were too lazy to support it when releasing the feature. If you really want it, please let us know!",
+ OpenCommitInBrowser: "Open commit in browser",
+ ViewBisectOptions: "View bisect options",
+ ConfirmRevertCommit: "Are you sure you want to revert {{.selectedCommit}}?",
+ RewordInEditorTitle: "Reword in editor",
+ RewordInEditorPrompt: "Are you sure you want to reword this commit in your editor?",
+ HardResetAutostashPrompt: "Are you sure you want to hard reset to '%s'? An auto-stash will be performed if necessary.",
+ CheckoutPrompt: "Are you sure you want to checkout '%s'?",
+ UpstreamGone: "(upstream gone)",
+ NukeDescription: "If you want to make all the changes in the worktree go away, this is the way to do it. If there are dirty submodule changes this will stash those changes in the submodule(s).",
+ DiscardStagedChangesDescription: "This will create a new stash entry containing only staged files and then drop it, so that the working tree is left with only unstaged changes",
+ EmptyOutput: "",
+ Patch: "Patch",
+ CustomPatch: "Custom patch",
+ CommitsCopied: "commits copied", // lowercase because it's used in a sentence
+ CommitCopied: "commit copied", // lowercase because it's used in a sentence
+ ResetPatch: "Reset patch",
+ ResetPatchTooltip: "Clear the current patch.",
+ ApplyPatch: "Apply patch",
+ ApplyPatchTooltip: "Apply the current patch to the working tree.",
+ ApplyPatchInReverse: "Apply patch in reverse",
+ ApplyPatchInReverseTooltip: "Apply the current patch in reverse to the working tree.",
+ RemovePatchFromOriginalCommit: "Remove patch from original commit (%s)",
+ RemovePatchFromOriginalCommitTooltip: "Remove the current patch from its commit. This is achieved by starting an interactive rebase at the commit, applying the patch in reverse, and then continuing the rebase. If later commits depend on the patch, you may need to resolve conflicts.",
+ MovePatchOutIntoIndex: "Move patch out into index",
+ MovePatchOutIntoIndexTooltip: "Move the patch out of its commit and into the index. This is achieved by starting an interactive rebase at the commit, applying the patch in reverse, continuing the rebase to completion, and then applying the patch to the index. If later commits depend on the patch, you may need to resolve conflicts.",
+ MovePatchIntoNewCommit: "Move patch into new commit",
+ MovePatchIntoNewCommitTooltip: "Move the patch out of its commit and into a new commit sitting on top of the original commit. This is achieved by starting an interactive rebase at the original commit, applying the patch in reverse, then applying the patch to the index and committing it as a new commit, before continuing the rebase to completion. If later commits depend on the patch, you may need to resolve conflicts.",
+ MovePatchToSelectedCommit: "Move patch to selected commit (%s)",
+ MovePatchToSelectedCommitTooltip: "Move the patch out of its original commit and into the selected commit. This is achieved by starting an interactive rebase at the original commit, applying the patch in reverse, then continuing the rebase up to the selected commit, before applying the patch forward and amending the seleced commit. The rebase is then continued to completion. If commits between the source and destination commit depend on the patch, you may need to resolve conflicts.",
+ CopyPatchToClipboard: "Copy patch to clipboard",
+ NoMatchesFor: "No matches for '%s' %s",
+ ExitSearchMode: "%s: Exit search mode",
+ ExitTextFilterMode: "%s: Exit filter mode",
+ MatchesFor: "matches for '%s' (%d of %d) %s", // lowercase because it's after other text
+ SearchKeybindings: "%s: Next match, %s: Previous match, %s: Exit search mode",
+ SearchPrefix: "Search: ",
+ FilterPrefix: "Filter: ",
+ WorktreesTitle: "Worktrees",
+ WorktreeTitle: "Worktree",
+ Switch: "Switch",
+ SwitchToWorktree: "Switch to worktree",
+ SwitchToWorktreeTooltip: "Switch to the selected worktree.",
+ AlreadyCheckedOutByWorktree: "This branch is checked out by worktree {{.worktreeName}}. Do you want to switch to that worktree?",
+ BranchCheckedOutByWorktree: "Branch {{.branchName}} is checked out by worktree {{.worktreeName}}",
+ DetachWorktreeTooltip: "This will run `git checkout --detach` on the worktree so that it stops hogging the branch, but the worktree's working tree will be left alone.",
+ Switching: "Switching",
+ RemoveWorktree: "Remove worktree",
+ RemoveWorktreeTitle: "Remove worktree",
+ RemoveWorktreePrompt: "Are you sure you want to remove worktree '{{.worktreeName}}'?",
+ ForceRemoveWorktreePrompt: "'{{.worktreeName}}' contains modified or untracked files (to be honest, it could contain both). Are you sure you want to remove it?",
+ RemovingWorktree: "Deleting worktree",
+ DetachWorktree: "Detach worktree",
+ DetachingWorktree: "Detaching worktree",
+ AddingWorktree: "Adding worktree",
+ CantDeleteCurrentWorktree: "You cannot remove the current worktree!",
+ AlreadyInWorktree: "You are already in the selected worktree",
+ CantDeleteMainWorktree: "You cannot remove the main worktree!",
+ NoWorktreesThisRepo: "No worktrees",
+ MissingWorktree: "(missing)",
+ MainWorktree: "(main)",
+ NewWorktree: "New worktree",
+ NewWorktreePath: "New worktree path",
+ NewWorktreeBase: "New worktree base ref",
+ RemoveWorktreeTooltip: "Remove the selected worktree. This will both delete the worktree's directory, as well as metadata about the worktree in the .git directory.",
+ BranchNameCannotBeBlank: "Branch name cannot be blank",
+ NewBranchName: "New branch name",
+ NewBranchNameLeaveBlank: "New branch name (leave blank to checkout {{.default}})",
+ ViewWorktreeOptions: "View worktree options",
+ CreateWorktreeFrom: "Create worktree from {{.ref}}",
+ CreateWorktreeFromDetached: "Create worktree from {{.ref}} (detached)",
+ LcWorktree: "worktree",
+ ChangingDirectoryTo: "Changing directory to {{.path}}",
+ Name: "Name",
+ Branch: "Branch",
+ Path: "Path",
+ MarkedBaseCommitStatus: "Marked a base commit for rebase",
+ MarkAsBaseCommit: "Mark as base commit for rebase",
+ MarkAsBaseCommitTooltip: "Select a base commit for the next rebase. When you rebase onto a branch, only commits above the base commit will be brought across. This uses the `git rebase --onto` command.",
+ MarkedCommitMarker: "↑↑↑ Will rebase from here ↑↑↑",
+ PleaseGoToURL: "Please go to {{.url}}",
+ DisabledMenuItemPrefix: "Disabled: ",
+ NoCopiedCommits: "No copied commits",
+ QuickStartInteractiveRebase: "Start interactive rebase",
+ QuickStartInteractiveRebaseTooltip: "Start an interactive rebase for the commits on your branch. This will include all commits from the HEAD commit down to the first merge commit or main branch commit.\nIf you would instead like to start an interactive rebase from the selected commit, press `{{.editKey}}`.",
+ CannotQuickStartInteractiveRebase: "Cannot start interactive rebase: the HEAD commit is a merge commit or is present on the main branch, so there is no appropriate base commit to start the rebase from. You can start an interactive rebase from a specific commit by selecting the commit and pressing `{{.editKey}}`.",
+ RangeSelectUp: "Range select up",
+ RangeSelectDown: "Range select down",
+ RangeSelectNotSupported: "Action does not support range selection, please select a single item",
+ NoItemSelected: "No item selected",
+ SelectedItemIsNotABranch: "Selected item is not a branch",
+ SelectedItemDoesNotHaveFiles: "Selected item does not have files to view",
+ RangeSelectNotSupportedForSubmodules: "Range select not supported for submodules",
+ OldCherryPickKeyWarning: "The 'c' key is no longer the default key for copying commits to cherry pick. Please use `{{.copy}}` instead (and `{{.paste}}` to paste). The reason for this change is that the 'v' key for selecting a range of lines when staging is now also used for selecting a range of lines in any list view, meaning that we needed to find a new key for pasting commits, and if we're going to now use `{{.paste}}` for pasting commits, we may as well use `{{.copy}}` for copying them. If you want to configure the keybindings to get the old behaviour, set the following in your config:\n\nkeybinding:\n universal:\n toggleRangeSelect: \n commits:\n cherryPickCopy: 'c'\n pasteCommits: 'v'",
+ CommandDoesNotSupportOpeningInEditor: "This command doesn't support switching to the editor",
Actions: Actions{
// TODO: combine this with the original keybinding descriptions (those are all in lowercase atm)
diff --git a/pkg/integration/tests/diff/rename_similarity_threshold_change.go b/pkg/integration/tests/diff/rename_similarity_threshold_change.go
new file mode 100644
index 000000000..170838fd3
--- /dev/null
+++ b/pkg/integration/tests/diff/rename_similarity_threshold_change.go
@@ -0,0 +1,41 @@
+package diff
+
+import (
+ "github.com/jesseduffield/lazygit/pkg/config"
+ . "github.com/jesseduffield/lazygit/pkg/integration/components"
+)
+
+var RenameSimilarityThresholdChange = NewIntegrationTest(NewIntegrationTestArgs{
+ Description: "Change the rename similarity threshold while in the commits panel",
+ ExtraCmdArgs: []string{},
+ Skip: false,
+ SetupConfig: func(config *config.AppConfig) {},
+ SetupRepo: func(shell *Shell) {
+ shell.CreateFileAndAdd("original", "one\ntwo\nthree\nfour\nfive\n")
+ shell.Commit("add original")
+
+ shell.DeleteFileAndAdd("original")
+ shell.CreateFileAndAdd("renamed", "one\ntwo\nthree\nfour\nfive\nsix\nseven\neight\nnine\nten\n")
+ shell.Commit("change name and contents")
+ },
+ Run: func(t *TestDriver, keys config.KeybindingConfig) {
+ t.Views().Commits().Focus()
+
+ t.Views().Main().
+ ContainsLines(
+ Contains("2 files changed, 10 insertions(+), 5 deletions(-)"),
+ )
+
+ t.Views().Commits().
+ Press(keys.Universal.DecreaseRenameSimilarityThreshold).
+ Tap(func() {
+ t.ExpectToast(Equals("Changed rename similarity threshold to 45%"))
+ })
+
+ t.Views().Main().
+ ContainsLines(
+ Contains("original => renamed"),
+ Contains("1 file changed, 5 insertions(+)"),
+ )
+ },
+})
diff --git a/pkg/integration/tests/file/rename_similarity_threshold_change.go b/pkg/integration/tests/file/rename_similarity_threshold_change.go
new file mode 100644
index 000000000..ec3aad241
--- /dev/null
+++ b/pkg/integration/tests/file/rename_similarity_threshold_change.go
@@ -0,0 +1,35 @@
+package file
+
+import (
+ "github.com/jesseduffield/lazygit/pkg/config"
+ . "github.com/jesseduffield/lazygit/pkg/integration/components"
+)
+
+var RenameSimilarityThresholdChange = NewIntegrationTest(NewIntegrationTestArgs{
+ Description: "Change the rename similarity threshold while in the files panel",
+ ExtraCmdArgs: []string{},
+ Skip: false,
+ SetupConfig: func(config *config.AppConfig) {},
+ SetupRepo: func(shell *Shell) {
+ shell.CreateFileAndAdd("original", "one\ntwo\nthree\nfour\nfive\n")
+ shell.Commit("add original")
+
+ shell.DeleteFileAndAdd("original")
+ shell.CreateFileAndAdd("renamed", "one\ntwo\nthree\nfour\nfive\nsix\nseven\neight\nnine\nten\n")
+ },
+ Run: func(t *TestDriver, keys config.KeybindingConfig) {
+ t.Views().Files().
+ IsFocused().
+ Lines(
+ Contains("D ").Contains("original"),
+ Contains("A ").Contains("renamed"),
+ ).
+ Press(keys.Universal.DecreaseRenameSimilarityThreshold).
+ Tap(func() {
+ t.ExpectToast(Equals("Changed rename similarity threshold to 45%"))
+ }).
+ Lines(
+ Contains("R ").Contains("original → renamed"),
+ )
+ },
+})
diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go
index fcc0b74bb..477fdee44 100644
--- a/pkg/integration/tests/test_list.go
+++ b/pkg/integration/tests/test_list.go
@@ -149,6 +149,7 @@ var tests = []*components.IntegrationTest{
diff.DiffAndApplyPatch,
diff.DiffCommits,
diff.IgnoreWhitespace,
+ diff.RenameSimilarityThresholdChange,
file.CopyMenu,
file.DirWithUntrackedFile,
file.DiscardAllDirChanges,
@@ -161,6 +162,7 @@ var tests = []*components.IntegrationTest{
file.DiscardVariousChangesRangeSelect,
file.Gitignore,
file.RememberCommitMessageAfterFail,
+ file.RenameSimilarityThresholdChange,
file.StageChildrenRangeSelect,
file.StageRangeSelect,
filter_and_search.FilterCommitFiles,
diff --git a/schema/config.json b/schema/config.json
index 23e052f69..eb93600a3 100644
--- a/schema/config.json
+++ b/schema/config.json
@@ -1322,6 +1322,14 @@
"type": "string",
"default": "{"
},
+ "increaseRenameSimilarityThreshold": {
+ "type": "string",
+ "default": ")"
+ },
+ "decreaseRenameSimilarityThreshold": {
+ "type": "string",
+ "default": "("
+ },
"openDiffTool": {
"type": "string",
"default": "\u003cc-t\u003e"
From f2db9fa3f91311fb42967234222bc510cf89b8bf Mon Sep 17 00:00:00 2001
From: Jesse Duffield
Date: Sat, 13 Jul 2024 14:54:09 +1000
Subject: [PATCH 24/36] Revert "Check for fixup commits on CI"
This reverts commit 7652d579f587c3202d1d80464557cfaa8005b3de.
Not working on forks, and I don't have time to fix right now
---
.github/workflows/ci.yml | 22 ----------------------
scripts/check_for_fixups.sh | 25 -------------------------
2 files changed, 47 deletions(-)
delete mode 100755 scripts/check_for_fixups.sh
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 9b0a04938..64c890894 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -219,25 +219,3 @@ jobs:
CODACY_PROJECT_TOKEN=${{ secrets.CODACY_PROJECT_TOKEN }} \
bash <(curl -Ls https://coverage.codacy.com/get.sh) report \
--force-coverage-parser go -r coverage.out
-
- check-for-fixups:
- runs-on: ubuntu-latest
- if: github.ref != 'refs/heads/master'
- steps:
- # See https://github.com/actions/checkout/issues/552#issuecomment-1167086216
- - name: "PR commits + 1"
- run: echo "PR_FETCH_DEPTH=$(( ${{ github.event.pull_request.commits }} + 1 ))" >> "${GITHUB_ENV}"
-
- - name: "Checkout PR branch and all PR commits"
- uses: actions/checkout@v4
- with:
- ref: ${{ github.event.pull_request.head.ref }}
- fetch-depth: ${{ env.PR_FETCH_DEPTH }}
-
- - name: "Fetch the other branch with enough history for a common merge-base commit"
- run: |
- git fetch origin ${{ github.event.pull_request.base.ref }}
-
- - name: Check for fixups
- run: |
- ./scripts/check_for_fixups.sh ${{ github.event.pull_request.base.ref }}
diff --git a/scripts/check_for_fixups.sh b/scripts/check_for_fixups.sh
deleted file mode 100755
index c2c2e1a21..000000000
--- a/scripts/check_for_fixups.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/sh
-
-base_ref=$1
-
-# Determine the base commit
-base_commit=$(git merge-base HEAD origin/"$base_ref")
-
-# Check if base_commit is set correctly
-if [ -z "$base_commit" ]; then
- echo "Failed to determine base commit."
- exit 1
-fi
-echo "Base commit: $base_commit"
-
-# Get commits with "fixup!" in the message from base_commit to HEAD
-commits=$(git log -i -P --grep "fixup\!" --format="%h %s" "$base_commit..HEAD")
-
-if [ -z "$commits" ]; then
- echo "No fixup commits found."
- exit 0
-else
- echo "Fixup commits found:"
- echo "$commits"
- exit 1
-fi
From 0489b11c0c161eb73801f841909f47654107045b Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Sat, 13 Jul 2024 05:03:33 +0000
Subject: [PATCH 25/36] README.md: Update Sponsors
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index f87a31840..890d2c7c7 100644
--- a/README.md
+++ b/README.md
@@ -46,7 +46,7 @@ A simple terminal UI for git commands
-


























































































+





























































































## Elevator Pitch
From da86096e19fc58a8b796f21cc0f8089bb64ad185 Mon Sep 17 00:00:00 2001
From: Stefan Haller
Date: Sat, 13 Jul 2024 11:35:15 +0200
Subject: [PATCH 26/36] Add test that demonstrates bug with language
auto-detection
---
pkg/i18n/i18n_test.go | 84 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 84 insertions(+)
diff --git a/pkg/i18n/i18n_test.go b/pkg/i18n/i18n_test.go
index 7023ea40a..28b96bc4f 100644
--- a/pkg/i18n/i18n_test.go
+++ b/pkg/i18n/i18n_test.go
@@ -2,8 +2,11 @@ package i18n
import (
"fmt"
+ "io"
+ "runtime"
"testing"
+ "github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
)
@@ -33,3 +36,84 @@ func TestDetectLanguage(t *testing.T) {
assert.EqualValues(t, s.expected, detectLanguage(s.langDetector))
}
}
+
+// Can't use utils.NewDummyLog() because of a cyclic dependency
+func newDummyLog() *logrus.Entry {
+ log := logrus.New()
+ log.Out = io.Discard
+ return log.WithField("test", "test")
+}
+
+func TestNewTranslationSetFromConfig(t *testing.T) {
+ if runtime.GOOS == "windows" {
+ // These tests are based on setting the LANG environment variable, which
+ // isn't respected on Windows.
+ t.Skip("Skipping test on Windows")
+ }
+
+ scenarios := []struct {
+ name string
+ configLanguage string
+ envLanguage string
+ expected string
+ expectedErr bool
+ }{
+ {
+ name: "configLanguage is nl",
+ configLanguage: "nl",
+ envLanguage: "en_US",
+ expected: "nl",
+ expectedErr: false,
+ },
+ {
+ name: "configLanguage is an unsupported language",
+ configLanguage: "xy",
+ envLanguage: "en_US",
+ expectedErr: true,
+ },
+ {
+ name: "auto-detection without LANG set",
+ configLanguage: "auto",
+ envLanguage: "",
+ expected: "en",
+ expectedErr: false,
+ },
+ {
+ name: "auto-detection with LANG set to nl_NL",
+ configLanguage: "auto",
+ envLanguage: "nl_NL",
+ expected: "nl",
+ expectedErr: true, // Demonstrates the bug, this should be false
+ },
+ {
+ name: "auto-detection with LANG set to zh-CN",
+ configLanguage: "auto",
+ envLanguage: "zh-CN",
+ expected: "zh-CN",
+ expectedErr: false,
+ },
+ {
+ name: "auto-detection with LANG set to an unsupported language",
+ configLanguage: "auto",
+ envLanguage: "xy_XY",
+ expected: "en",
+ expectedErr: false,
+ },
+ }
+
+ for _, s := range scenarios {
+ t.Run(s.name, func(t *testing.T) {
+ log := newDummyLog()
+ t.Setenv("LANG", s.envLanguage)
+ actualTranslationSet, err := NewTranslationSetFromConfig(log, s.configLanguage)
+ if s.expectedErr {
+ assert.Error(t, err)
+ } else {
+ assert.NoError(t, err)
+
+ expectedTranslationSet, _ := newTranslationSet(log, s.expected)
+ assert.Equal(t, expectedTranslationSet, actualTranslationSet)
+ }
+ })
+ }
+}
From ae4a579153bbe799a785c27f956bca5be46e429c Mon Sep 17 00:00:00 2001
From: Stefan Haller
Date: Sat, 13 Jul 2024 11:10:38 +0200
Subject: [PATCH 27/36] Fix language auto-detection
Starting lazygit with an environment containing LANG=ko_KO or LANG=nl_NL would
result in an error at startup.
---
pkg/i18n/i18n.go | 2 +-
pkg/i18n/i18n_test.go | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/pkg/i18n/i18n.go b/pkg/i18n/i18n.go
index f9febbe01..3848d42cf 100644
--- a/pkg/i18n/i18n.go
+++ b/pkg/i18n/i18n.go
@@ -24,7 +24,7 @@ func NewTranslationSetFromConfig(log *logrus.Entry, configLanguage string) (*Tra
language := detectLanguage(jibber_jabber.DetectIETF)
for _, languageCode := range languageCodes {
if strings.HasPrefix(language, languageCode) {
- return newTranslationSet(log, language)
+ return newTranslationSet(log, languageCode)
}
}
diff --git a/pkg/i18n/i18n_test.go b/pkg/i18n/i18n_test.go
index 28b96bc4f..8c5787fcb 100644
--- a/pkg/i18n/i18n_test.go
+++ b/pkg/i18n/i18n_test.go
@@ -83,7 +83,7 @@ func TestNewTranslationSetFromConfig(t *testing.T) {
configLanguage: "auto",
envLanguage: "nl_NL",
expected: "nl",
- expectedErr: true, // Demonstrates the bug, this should be false
+ expectedErr: false,
},
{
name: "auto-detection with LANG set to zh-CN",
From 1919a2d2d65682726decf32ae1404dc5cc507012 Mon Sep 17 00:00:00 2001
From: Stefan Haller
Date: Sat, 13 Jul 2024 14:08:44 +0200
Subject: [PATCH 28/36] Reapply "Check for fixup commits on CI"
This reverts commit f2db9fa3f91311fb42967234222bc510cf89b8bf.
---
.github/workflows/ci.yml | 22 ++++++++++++++++++++++
scripts/check_for_fixups.sh | 25 +++++++++++++++++++++++++
2 files changed, 47 insertions(+)
create mode 100755 scripts/check_for_fixups.sh
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 64c890894..9b0a04938 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -219,3 +219,25 @@ jobs:
CODACY_PROJECT_TOKEN=${{ secrets.CODACY_PROJECT_TOKEN }} \
bash <(curl -Ls https://coverage.codacy.com/get.sh) report \
--force-coverage-parser go -r coverage.out
+
+ check-for-fixups:
+ runs-on: ubuntu-latest
+ if: github.ref != 'refs/heads/master'
+ steps:
+ # See https://github.com/actions/checkout/issues/552#issuecomment-1167086216
+ - name: "PR commits + 1"
+ run: echo "PR_FETCH_DEPTH=$(( ${{ github.event.pull_request.commits }} + 1 ))" >> "${GITHUB_ENV}"
+
+ - name: "Checkout PR branch and all PR commits"
+ uses: actions/checkout@v4
+ with:
+ ref: ${{ github.event.pull_request.head.ref }}
+ fetch-depth: ${{ env.PR_FETCH_DEPTH }}
+
+ - name: "Fetch the other branch with enough history for a common merge-base commit"
+ run: |
+ git fetch origin ${{ github.event.pull_request.base.ref }}
+
+ - name: Check for fixups
+ run: |
+ ./scripts/check_for_fixups.sh ${{ github.event.pull_request.base.ref }}
diff --git a/scripts/check_for_fixups.sh b/scripts/check_for_fixups.sh
new file mode 100755
index 000000000..c2c2e1a21
--- /dev/null
+++ b/scripts/check_for_fixups.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+base_ref=$1
+
+# Determine the base commit
+base_commit=$(git merge-base HEAD origin/"$base_ref")
+
+# Check if base_commit is set correctly
+if [ -z "$base_commit" ]; then
+ echo "Failed to determine base commit."
+ exit 1
+fi
+echo "Base commit: $base_commit"
+
+# Get commits with "fixup!" in the message from base_commit to HEAD
+commits=$(git log -i -P --grep "fixup\!" --format="%h %s" "$base_commit..HEAD")
+
+if [ -z "$commits" ]; then
+ echo "No fixup commits found."
+ exit 0
+else
+ echo "Fixup commits found:"
+ echo "$commits"
+ exit 1
+fi
From 463cf35e64f0a6e1d74ca3ece49064306a039ab8 Mon Sep 17 00:00:00 2001
From: Stefan Haller
Date: Sat, 13 Jul 2024 14:39:28 +0200
Subject: [PATCH 29/36] Make checkout action work with forks
---
.github/workflows/ci.yml | 1 +
1 file changed, 1 insertion(+)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 9b0a04938..2143d3910 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -231,6 +231,7 @@ jobs:
- name: "Checkout PR branch and all PR commits"
uses: actions/checkout@v4
with:
+ repository: ${{ github.event.pull_request.head.repo.full_name }}
ref: ${{ github.event.pull_request.head.ref }}
fetch-depth: ${{ env.PR_FETCH_DEPTH }}
From 891362dfb2dd525e1cc824e0c4c7ac19efbdf3de Mon Sep 17 00:00:00 2001
From: Stefan Haller
Date: Sat, 13 Jul 2024 15:01:19 +0200
Subject: [PATCH 30/36] Use extended regex rather than perl regex in the git
call
My local git is not compiled with PCRE support, so using -E makes it easier for
me to test the script locally. And -E is good enough for the simple matching we
want to do here.
---
scripts/check_for_fixups.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/check_for_fixups.sh b/scripts/check_for_fixups.sh
index c2c2e1a21..12a07e3fd 100755
--- a/scripts/check_for_fixups.sh
+++ b/scripts/check_for_fixups.sh
@@ -13,7 +13,7 @@ fi
echo "Base commit: $base_commit"
# Get commits with "fixup!" in the message from base_commit to HEAD
-commits=$(git log -i -P --grep "fixup\!" --format="%h %s" "$base_commit..HEAD")
+commits=$(git log -i -E --grep "fixup\!" --format="%h %s" "$base_commit..HEAD")
if [ -z "$commits" ]; then
echo "No fixup commits found."
From 20ccb03a4545aa59f8fc0caafa1cbeda331a2f54 Mon Sep 17 00:00:00 2001
From: Stefan Haller
Date: Sat, 13 Jul 2024 14:47:37 +0200
Subject: [PATCH 31/36] Extend check for fixups
Also check for squash! and amend! (these are all anchored to the beginning of
the subject), and WIP and DROPME for good measure (but only if they occur in the
first line, otherwise it wouldn't let me merge this very commit :)
---
scripts/check_for_fixups.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/scripts/check_for_fixups.sh b/scripts/check_for_fixups.sh
index 12a07e3fd..31ed8640e 100755
--- a/scripts/check_for_fixups.sh
+++ b/scripts/check_for_fixups.sh
@@ -13,13 +13,13 @@ fi
echo "Base commit: $base_commit"
# Get commits with "fixup!" in the message from base_commit to HEAD
-commits=$(git log -i -E --grep "fixup\!" --format="%h %s" "$base_commit..HEAD")
+commits=$(git log -i -E --grep '^fixup!' --grep '^squash!' --grep '^amend!' --grep '^[^\n]*WIP' --grep '^[^\n]*DROPME' --format="%h %s" "$base_commit..HEAD")
if [ -z "$commits" ]; then
echo "No fixup commits found."
exit 0
else
- echo "Fixup commits found:"
+ echo "Fixup or WIP commits found:"
echo "$commits"
exit 1
fi
From 37f35da4365479db36951f696c9fedb57dbc1f98 Mon Sep 17 00:00:00 2001
From: Stefan Haller
Date: Fri, 26 Jul 2024 10:59:00 +0200
Subject: [PATCH 32/36] Add a readme file for the JSON files in
pkg/i18n/translations
People have started sending PRs that change these files.
---
pkg/i18n/translations/README.md | 3 +++
1 file changed, 3 insertions(+)
create mode 100644 pkg/i18n/translations/README.md
diff --git a/pkg/i18n/translations/README.md b/pkg/i18n/translations/README.md
new file mode 100644
index 000000000..ee8d561e1
--- /dev/null
+++ b/pkg/i18n/translations/README.md
@@ -0,0 +1,3 @@
+The JSON files in this directory are machine-generated; please do not edit.
+
+Translating lazygit happens at https://crowdin.com/project/lazygit/.
From 206b2c6f0be8d61fae225dbaa9c2af097ebeae20 Mon Sep 17 00:00:00 2001
From: Yam Liu <1056803+yam-liu@users.noreply.github.com>
Date: Thu, 1 Aug 2024 03:51:36 +0000
Subject: [PATCH 33/36] Add a unit test case for global context
---
.../tests/custom_commands/global_context.go | 61 +++++++++++++++++++
pkg/integration/tests/test_list.go | 1 +
2 files changed, 62 insertions(+)
create mode 100644 pkg/integration/tests/custom_commands/global_context.go
diff --git a/pkg/integration/tests/custom_commands/global_context.go b/pkg/integration/tests/custom_commands/global_context.go
new file mode 100644
index 000000000..8f8518559
--- /dev/null
+++ b/pkg/integration/tests/custom_commands/global_context.go
@@ -0,0 +1,61 @@
+package custom_commands
+
+import (
+ "github.com/jesseduffield/lazygit/pkg/config"
+ . "github.com/jesseduffield/lazygit/pkg/integration/components"
+)
+
+var GlobalContext = NewIntegrationTest(NewIntegrationTestArgs{
+ Description: "Ensure global context works",
+ ExtraCmdArgs: []string{},
+ Skip: false,
+ SetupRepo: func(shell *Shell) {
+ shell.EmptyCommit("my change")
+ },
+ SetupConfig: func(cfg *config.AppConfig) {
+ cfg.UserConfig.CustomCommands = []config.CustomCommand{
+ {
+ Key: "X",
+ Context: "global",
+ Command: "touch myfile",
+ ShowOutput: false,
+ },
+ }
+ },
+ Run: func(t *TestDriver, keys config.KeybindingConfig) {
+ // commits
+ t.Views().Commits().
+ Focus().
+ Press("X")
+
+ t.Views().Files().
+ Focus().
+ Lines(Contains("myfile"))
+
+ t.Shell().DeleteFile("myfile")
+ t.GlobalPress(keys.Files.RefreshFiles)
+
+ // branches
+ t.Views().Branches().
+ Focus().
+ Press("X")
+
+ t.Views().Files().
+ Focus().
+ Lines(Contains("myfile"))
+
+ t.Shell().DeleteFile("myfile")
+ t.GlobalPress(keys.Files.RefreshFiles)
+
+ // files
+ t.Views().Files().
+ Focus().
+ Press("X")
+
+ t.Views().Files().
+ Focus().
+ Lines(Contains("myfile"))
+
+ t.Shell().DeleteFile("myfile")
+ },
+})
diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go
index 477fdee44..50d68e85c 100644
--- a/pkg/integration/tests/test_list.go
+++ b/pkg/integration/tests/test_list.go
@@ -122,6 +122,7 @@ var tests = []*components.IntegrationTest{
custom_commands.DeleteFromHistory,
custom_commands.EditHistory,
custom_commands.FormPrompts,
+ custom_commands.GlobalContext,
custom_commands.History,
custom_commands.MenuFromCommand,
custom_commands.MenuFromCommandsOutput,
From 542030f1906de56001009b581ed1c936e4503f7f Mon Sep 17 00:00:00 2001
From: Yam Liu <1056803+yam-liu@users.noreply.github.com>
Date: Sat, 27 Jul 2024 16:40:41 +0000
Subject: [PATCH 34/36] Support multiple contexts within one command, add
tests, update doc
---
docs/Custom_Command_Keybindings.md | 5 ++
pkg/gui/services/custom_commands/client.go | 4 +-
.../custom_commands/keybinding_creator.go | 43 +++++++++-----
.../custom_commands/multiple_contexts.go | 58 +++++++++++++++++++
pkg/integration/tests/test_list.go | 1 +
5 files changed, 93 insertions(+), 18 deletions(-)
create mode 100644 pkg/integration/tests/custom_commands/multiple_contexts.go
diff --git a/docs/Custom_Command_Keybindings.md b/docs/Custom_Command_Keybindings.md
index 1053f9e45..dd7c11af7 100644
--- a/docs/Custom_Command_Keybindings.md
+++ b/docs/Custom_Command_Keybindings.md
@@ -87,6 +87,11 @@ The permitted contexts are:
| stash | The 'Stash' tab |
| global | This keybinding will take affect everywhere |
+> **Bonus**
+>
+> You can use a comma-separated string, such as `context: 'commits, subCommits'`, to make it effective in multiple contexts.
+
+
## Prompts
### Common fields
diff --git a/pkg/gui/services/custom_commands/client.go b/pkg/gui/services/custom_commands/client.go
index c746f0579..571445424 100644
--- a/pkg/gui/services/custom_commands/client.go
+++ b/pkg/gui/services/custom_commands/client.go
@@ -39,11 +39,11 @@ func (self *Client) GetCustomCommandKeybindings() ([]*types.Binding, error) {
bindings := []*types.Binding{}
for _, customCommand := range self.customCommands {
handler := self.handlerCreator.call(customCommand)
- binding, err := self.keybindingCreator.call(customCommand, handler)
+ compoundBindings, err := self.keybindingCreator.call(customCommand, handler)
if err != nil {
return nil, err
}
- bindings = append(bindings, binding)
+ bindings = append(bindings, compoundBindings...)
}
return bindings, nil
diff --git a/pkg/gui/services/custom_commands/keybinding_creator.go b/pkg/gui/services/custom_commands/keybinding_creator.go
index 2a65c1324..4e6f9d8c7 100644
--- a/pkg/gui/services/custom_commands/keybinding_creator.go
+++ b/pkg/gui/services/custom_commands/keybinding_creator.go
@@ -24,12 +24,12 @@ func NewKeybindingCreator(c *helpers.HelperCommon) *KeybindingCreator {
}
}
-func (self *KeybindingCreator) call(customCommand config.CustomCommand, handler func() error) (*types.Binding, error) {
+func (self *KeybindingCreator) call(customCommand config.CustomCommand, handler func() error) ([]*types.Binding, error) {
if customCommand.Context == "" {
return nil, formatContextNotProvidedError(customCommand)
}
- viewName, err := self.getViewNameAndContexts(customCommand)
+ viewNames, err := self.getViewNamesAndContexts(customCommand)
if err != nil {
return nil, err
}
@@ -39,27 +39,38 @@ func (self *KeybindingCreator) call(customCommand config.CustomCommand, handler
description = customCommand.Command
}
- return &types.Binding{
- ViewName: viewName,
- Key: keybindings.GetKey(customCommand.Key),
- Modifier: gocui.ModNone,
- Handler: handler,
- Description: description,
- }, nil
+ return lo.Map(viewNames, func(viewName string, _ int) *types.Binding {
+ return &types.Binding{
+ ViewName: viewName,
+ Key: keybindings.GetKey(customCommand.Key),
+ Modifier: gocui.ModNone,
+ Handler: handler,
+ Description: description,
+ }
+ }), nil
}
-func (self *KeybindingCreator) getViewNameAndContexts(customCommand config.CustomCommand) (string, error) {
+func (self *KeybindingCreator) getViewNamesAndContexts(customCommand config.CustomCommand) ([]string, error) {
if customCommand.Context == "global" {
- return "", nil
+ return []string{""}, nil
}
- ctx, ok := self.contextForContextKey(types.ContextKey(customCommand.Context))
- if !ok {
- return "", formatUnknownContextError(customCommand)
+ contexts := strings.Split(customCommand.Context, ",")
+ contexts = lo.Map(contexts, func(context string, _ int) string {
+ return strings.TrimSpace(context)
+ })
+
+ viewNames := []string{}
+ for _, context := range contexts {
+ ctx, ok := self.contextForContextKey(types.ContextKey(context))
+ if !ok {
+ return []string{}, formatUnknownContextError(customCommand)
+ }
+
+ viewNames = append(viewNames, ctx.GetViewName())
}
- viewName := ctx.GetViewName()
- return viewName, nil
+ return viewNames, nil
}
func (self *KeybindingCreator) contextForContextKey(contextKey types.ContextKey) (types.Context, bool) {
diff --git a/pkg/integration/tests/custom_commands/multiple_contexts.go b/pkg/integration/tests/custom_commands/multiple_contexts.go
new file mode 100644
index 000000000..3edc6e907
--- /dev/null
+++ b/pkg/integration/tests/custom_commands/multiple_contexts.go
@@ -0,0 +1,58 @@
+package custom_commands
+
+import (
+ "github.com/jesseduffield/lazygit/pkg/config"
+ . "github.com/jesseduffield/lazygit/pkg/integration/components"
+)
+
+var MultipleContexts = NewIntegrationTest(NewIntegrationTestArgs{
+ Description: "Test that multiple contexts works",
+ ExtraCmdArgs: []string{},
+ Skip: false,
+ SetupRepo: func(shell *Shell) {
+ shell.EmptyCommit("my change")
+ },
+ SetupConfig: func(cfg *config.AppConfig) {
+ cfg.UserConfig.CustomCommands = []config.CustomCommand{
+ {
+ Key: "X",
+ Context: "commits, reflogCommits",
+ Command: "touch myfile",
+ ShowOutput: false,
+ },
+ }
+ },
+ Run: func(t *TestDriver, keys config.KeybindingConfig) {
+ // commits
+ t.Views().Commits().
+ Focus().
+ Press("X")
+
+ t.Views().Files().
+ Focus().
+ Lines(Contains("myfile"))
+
+ t.Shell().DeleteFile("myfile")
+ t.GlobalPress(keys.Files.RefreshFiles)
+
+ // branches
+ t.Views().Branches().
+ Focus().
+ Press("X")
+
+ t.Views().Files().
+ Focus().
+ IsEmpty()
+
+ // files
+ t.Views().ReflogCommits().
+ Focus().
+ Press("X")
+
+ t.Views().Files().
+ Focus().
+ Lines(Contains("myfile"))
+
+ t.Shell().DeleteFile("myfile")
+ },
+})
diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go
index 50d68e85c..7c52d76e9 100644
--- a/pkg/integration/tests/test_list.go
+++ b/pkg/integration/tests/test_list.go
@@ -126,6 +126,7 @@ var tests = []*components.IntegrationTest{
custom_commands.History,
custom_commands.MenuFromCommand,
custom_commands.MenuFromCommandsOutput,
+ custom_commands.MultipleContexts,
custom_commands.MultiplePrompts,
custom_commands.OmitFromHistory,
custom_commands.ShowOutputInPanel,
From ef4fd70f9c6225dbc9401a5efad4ca0bdad827f8 Mon Sep 17 00:00:00 2001
From: ppoum
Date: Sat, 3 Aug 2024 09:58:43 -0400
Subject: [PATCH 35/36] Ignore GetRepoPaths error when launching
---
pkg/app/app.go | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/pkg/app/app.go b/pkg/app/app.go
index e12461e28..755f707c4 100644
--- a/pkg/app/app.go
+++ b/pkg/app/app.go
@@ -118,11 +118,11 @@ func NewApp(config config.AppConfigurer, test integrationTypes.IntegrationTest,
return app, err
}
- // If we're not in a repo, repoPaths will be nil. The error is moot for us
+ // If we're not in a repo, GetRepoPaths will return an error. The error is moot for us
// at this stage, since we'll try to init a new repo in setupRepo(), below
repoPaths, err := git_commands.GetRepoPaths(app.OSCommand.Cmd, gitVersion)
if err != nil {
- return app, err
+ common.Log.Infof("Error getting repo paths: %v", err)
}
showRecentRepos, err := app.setupRepo(repoPaths)
From cb53e377a8a999b289006374f5f94de671c170af Mon Sep 17 00:00:00 2001
From: hasecilu
Date: Thu, 8 Aug 2024 15:18:02 -0600
Subject: [PATCH 36/36] Fix lack of icon assignation when extension don't match
capitalization
---
pkg/gui/presentation/icons/file_icons.go | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/pkg/gui/presentation/icons/file_icons.go b/pkg/gui/presentation/icons/file_icons.go
index 8f639a4ee..0b4159f06 100644
--- a/pkg/gui/presentation/icons/file_icons.go
+++ b/pkg/gui/presentation/icons/file_icons.go
@@ -2,6 +2,7 @@ package icons
import (
"path/filepath"
+ "strings"
)
// NOTE: Visit next links for inspiration:
@@ -728,7 +729,7 @@ func IconForFile(name string, isSubmodule bool, isLinkedWorktree bool, isDirecto
return icon
}
- ext := filepath.Ext(name)
+ ext := strings.ToLower(filepath.Ext(name))
if icon, ok := extIconMap[ext]; ok {
return icon
}