add colored prompt

- user@host in bold green (bold red for root), directory in bold blue
- colors are disabled with NO_COLOR, TERM=dumb or when stdout is not a terminal
- parts are sanitized before adding the color codes
- only replace the home directory with ~ on a path boundary

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Florian WaltherandClaude Opus 5.5 committed 2026-10-03 17:31:09 +02:00
1 parent 37d6802815
commit 7afcecd053
3 files changed
+78 -7

No files matched your search

+36
View File
@@ -1004,6 +1004,7 @@ func TestSanitize(t *testing.T) {
}
func TestGetPrompt_EscapesControlCharacters(t *testing.T) {
t.Setenv("NO_COLOR", "1")
origDir, _ := os.Getwd()
defer os.Chdir(origDir)
@@ -1024,6 +1025,41 @@ func TestGetPrompt_EscapesControlCharacters(t *testing.T) {
}
}
func TestBuildPrompt_Color(t *testing.T) {
got := buildPrompt("flow", "host", "~/src", false, true)
want := colorUser + "flow@host" + colorReset + ":" + colorPath + "~/src" + colorReset + " $ "
if got != want {
t.Errorf("buildPrompt() = %q, want %q", got, want)
}
got = buildPrompt("root", "host", "/", true, true)
if !strings.HasPrefix(got, colorRoot+"root@host") {
t.Errorf("expected red user for root, got %q", got)
}
got = buildPrompt("flow", "host", "~/src", false, false)
if got != "flow@host:~/src $ " {
t.Errorf("buildPrompt() without color = %q", got)
}
}
func TestBuildPrompt_ColorEscapesControlCharacters(t *testing.T) {
got := buildPrompt("flow", "host", "evil\x1b[2J\x07", false, true)
if strings.Contains(got, "\x1b[2J") || strings.Contains(got, "\x07") {
t.Errorf("prompt contains control characters from path: %q", got)
}
if !strings.Contains(got, `evil\x1b[2J\x07`) {
t.Errorf("expected escaped path in prompt, got %q", got)
}
}
func TestUseColor_NoColor(t *testing.T) {
t.Setenv("NO_COLOR", "1")
if useColor() {
t.Error("expected no color when NO_COLOR is set")
}
}
func TestFilePathCompleter_SkipsControlCharacters(t *testing.T) {
dir := t.TempDir()
for _, name := range []string{"good", "go\x1b[31mred"} {