This commit is contained in:
Rabin Yasharzadehe 2026-09-09 18:23:04 +09:00 committed by GitHub
commit 8cd5b63505
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 124 additions and 3 deletions

View file

@ -358,6 +358,11 @@ gui:
# is already active, go to next tab instead
switchTabsWithPanelJumpKeys: false
# Format string for the terminal window title. Supports placeholders:
# - {{repoName}}: Name of the current repository
# Set to empty string to disable terminal title updates.
terminalTitle: lazygit::{{repoName}}
# Config relating to git
git:
# Array of diff renderers. Each entry has the following format:

View file

@ -222,6 +222,10 @@ type GuiConfig struct {
SwitchToFilesAfterStashApply bool `yaml:"switchToFilesAfterStashApply"`
// If true, when using the panel jump keys (default 1 through 5) and target panel is already active, go to next tab instead
SwitchTabsWithPanelJumpKeys bool `yaml:"switchTabsWithPanelJumpKeys"`
// Format string for the terminal window title. Supports placeholders:
// - {{repoName}}: Name of the current repository
// Set to empty string to disable terminal title updates.
TerminalTitle string `yaml:"terminalTitle"`
}
func (c *GuiConfig) UseFuzzySearch() bool {
@ -934,6 +938,7 @@ func GetDefaultConfigForPlatform(platform string) *UserConfig {
SwitchToFilesAfterStashPop: true,
SwitchToFilesAfterStashApply: true,
SwitchTabsWithPanelJumpKeys: false,
TerminalTitle: "lazygit::{{repoName}}",
},
Git: GitConfig{
Commit: CommitConfig{

View file

@ -533,6 +533,8 @@ func (gui *Gui) onUserConfigLoaded() error {
presentation.SetCustomBranches(userConfig.Gui.BranchColors, false)
}
gui.updateTerminalTitle()
return nil
}
@ -1141,13 +1143,35 @@ func (gui *Gui) loadNewRepo() error {
}
refresh(options)
if err := gui.os.UpdateWindowTitle(); err != nil {
return err
}
gui.updateTerminalTitle()
return nil
}
func (gui *Gui) updateTerminalTitle() {
titleFormat := gui.c.UserConfig().Gui.TerminalTitle
if titleFormat == "" {
return
}
// gui.git may not be set yet during initial startup
if gui.git == nil || gui.git.RepoPaths == nil {
return
}
repoName := gui.git.RepoPaths.RepoName()
title := utils.ResolvePlaceholderString(titleFormat, map[string]string{
"repoName": repoName,
})
// Sanitize title by removing control characters that could break terminal behavior
title = utils.SanitizeTerminalTitle(title)
if gocui.Screen != nil {
gocui.Screen.SetTitle(title)
}
}
func (gui *Gui) showIntroPopupMessage() {
gui.waitForIntro.Add(1)

View file

@ -31,3 +31,15 @@ func ResolvePlaceholderString(str string, arguments map[string]string) string {
}
return strings.NewReplacer(oldnews...).Replace(str)
}
// SanitizeTerminalTitle removes control characters from a string intended
// for use as a terminal title. Control characters (ASCII 0-31 and 127) could
// break terminal behavior or be used for escape sequence injection.
func SanitizeTerminalTitle(title string) string {
return strings.Map(func(r rune) rune {
if r < 32 || r == 127 {
return -1 // Remove control characters
}
return r
}, title)
}

View file

@ -66,3 +66,73 @@ func TestResolvePlaceholderString(t *testing.T) {
assert.EqualValues(t, s.expected, ResolvePlaceholderString(s.templateString, s.arguments))
}
}
func TestSanitizeTerminalTitle(t *testing.T) {
scenarios := []struct {
name string
input string
expected string
}{
{
name: "normal string",
input: "lazygit::myproject",
expected: "lazygit::myproject",
},
{
name: "empty string",
input: "",
expected: "",
},
{
name: "string with spaces",
input: "lazygit :: my project",
expected: "lazygit :: my project",
},
{
name: "string with unicode",
input: "lazygit::项目",
expected: "lazygit::项目",
},
{
name: "removes null byte",
input: "lazy\x00git",
expected: "lazygit",
},
{
name: "removes escape sequence",
input: "lazy\x1b[31mgit",
expected: "lazy[31mgit",
},
{
name: "removes newline and tab",
input: "lazy\ngit\ttitle",
expected: "lazygittitle",
},
{
name: "removes carriage return",
input: "lazy\rgit",
expected: "lazygit",
},
{
name: "removes DEL character",
input: "lazy\x7fgit",
expected: "lazygit",
},
{
name: "removes bell character",
input: "lazy\x07git",
expected: "lazygit",
},
{
name: "preserves printable special chars",
input: "lazy&git|test<>",
expected: "lazy&git|test<>",
},
}
for _, s := range scenarios {
t.Run(s.name, func(t *testing.T) {
assert.EqualValues(t, s.expected, SanitizeTerminalTitle(s.input))
})
}
}

View file

@ -925,6 +925,11 @@
"type": "boolean",
"description": "If true, when using the panel jump keys (default 1 through 5) and target panel is already active, go to next tab instead",
"default": false
},
"terminalTitle": {
"type": "string",
"description": "Format string for the terminal window title. Supports placeholders:\n- {{repoName}}: Name of the current repository\nSet to empty string to disable terminal title updates.",
"default": "lazygit::{{repoName}}"
}
},
"additionalProperties": false,