refactor: move formats to shell

This commit is contained in:
Jan De Dobbeleer 2024-07-01 21:25:01 +02:00 committed by Jan De Dobbeleer
parent 0a4a589125
commit 4c34ffdc32
3 changed files with 139 additions and 130 deletions

110
src/shell/formats.go Normal file
View file

@ -0,0 +1,110 @@
package shell
type Formats struct {
Escape string
Left string
Linechange string
ClearBelow string
ClearLine string
Title string
SaveCursorPosition string
RestoreCursorPosition string
Osc99 string
Osc7 string
Osc51 string
EscapeSequences map[rune]rune
HyperlinkStart string
HyperlinkCenter string
HyperlinkEnd string
ITermPromptMark string
ITermCurrentDir string
ITermRemoteHost string
}
func GetFormats(shell string) *Formats {
var formats *Formats
switch shell {
case BASH:
formats = &Formats{
Escape: "\\[%s\\]",
Linechange: "\\[\x1b[%d%s\\]",
Left: "\\[\x1b[%dD\\]",
ClearBelow: "\\[\x1b[0J\\]",
ClearLine: "\\[\x1b[K\\]",
SaveCursorPosition: "\\[\x1b7\\]",
RestoreCursorPosition: "\\[\x1b8\\]",
Title: "\\[\x1b]0;%s\007\\]",
HyperlinkStart: "\\[\x1b]8;;",
HyperlinkCenter: "\x1b\\\\\\]",
HyperlinkEnd: "\\[\x1b]8;;\x1b\\\\\\]",
Osc99: "\\[\x1b]9;9;%s\x1b\\\\\\]",
Osc7: "\\[\x1b]7;file://%s/%s\x1b\\\\\\]",
Osc51: "\\[\x1b]51;A;%s@%s:%s\x1b\\\\\\]",
ITermPromptMark: "\\[$(iterm2_prompt_mark)\\]",
ITermCurrentDir: "\\[\x1b]1337;CurrentDir=%s\x07\\]",
ITermRemoteHost: "\\[\x1b]1337;RemoteHost=%s@%s\x07\\]",
EscapeSequences: map[rune]rune{
96: 92, // backtick
92: 92, // backslash
},
}
case ZSH, TCSH:
formats = &Formats{
Escape: "%%{%s%%}",
Linechange: "%%{\x1b[%d%s%%}",
Left: "%%{\x1b[%dD%%}",
ClearBelow: "%{\x1b[0J%}",
ClearLine: "%{\x1b[K%}",
SaveCursorPosition: "%{\x1b7%}",
RestoreCursorPosition: "%{\x1b8%}",
Title: "%%{\x1b]0;%s\007%%}",
HyperlinkStart: "%{\x1b]8;;",
HyperlinkCenter: "\x1b\\%}",
HyperlinkEnd: "%{\x1b]8;;\x1b\\%}",
Osc99: "%%{\x1b]9;9;%s\x1b\\%%}",
Osc7: "%%{\x1b]7;file://%s/%s\x1b\\%%}",
Osc51: "%%{\x1b]51;A%s@%s:%s\x1b\\%%}",
ITermPromptMark: "%{$(iterm2_prompt_mark)%}",
ITermCurrentDir: "%%{\x1b]1337;CurrentDir=%s\x07%%}",
ITermRemoteHost: "%%{\x1b]1337;RemoteHost=%s@%s\x07%%}",
}
default:
formats = &Formats{
Escape: "%s",
Linechange: "\x1b[%d%s",
Left: "\x1b[%dD",
ClearBelow: "\x1b[0J",
ClearLine: "\x1b[K",
SaveCursorPosition: "\x1b7",
RestoreCursorPosition: "\x1b8",
Title: "\x1b]0;%s\007",
// when in fish on Linux, it seems hyperlinks ending with \\ print a \
// unlike on macOS. However, this is a fish bug, so do not try to fix it here:
// https://github.com/JanDeDobbeleer/oh-my-posh/pull/3288#issuecomment-1369137068
HyperlinkStart: "\x1b]8;;",
HyperlinkCenter: "\x1b\\",
HyperlinkEnd: "\x1b]8;;\x1b\\",
Osc99: "\x1b]9;9;%s\x1b\\",
Osc7: "\x1b]7;file://%s/%s\x1b\\",
Osc51: "\x1b]51;A%s@%s:%s\x1b\\",
ITermCurrentDir: "\x1b]1337;CurrentDir=%s\x07",
ITermRemoteHost: "\x1b]1337;RemoteHost=%s@%s\x07",
}
}
if shell == ZSH {
formats.EscapeSequences = map[rune]rune{
96: 92, // backtick
37: 37, // %
}
}
return formats
}

View file

@ -39,11 +39,11 @@ func RenderItermFeatures(features ITermFeatures, sh, pwd, user, host string) str
continue continue
} }
result.WriteString(formats.iTermPromptMark) result.WriteString(formats.ITermPromptMark)
case CurrentDir: case CurrentDir:
result.WriteString(fmt.Sprintf(formats.iTermCurrentDir, pwd)) result.WriteString(fmt.Sprintf(formats.ITermCurrentDir, pwd))
case RemoteHost: case RemoteHost:
result.WriteString(fmt.Sprintf(formats.iTermRemoteHost, user, host)) result.WriteString(fmt.Sprintf(formats.ITermRemoteHost, user, host))
} }
} }

View file

@ -69,36 +69,9 @@ var (
Shell string Shell string
Program string Program string
formats *shellFormats formats *shell.Formats
) )
type shellFormats struct {
escape string
left string
linechange string
clearBelow string
clearLine string
title string
saveCursorPosition string
restoreCursorPosition string
osc99 string
osc7 string
osc51 string
escapeSequences map[rune]rune
hyperlinkStart string
hyperlinkCenter string
hyperlinkEnd string
iTermPromptMark string
iTermCurrentDir string
iTermRemoteHost string
}
const ( const (
// Transparent implies a transparent color // Transparent implies a transparent color
Transparent = "transparent" Transparent = "transparent"
@ -153,81 +126,7 @@ func Init(sh string) {
trueColor = Program != AppleTerminal trueColor = Program != AppleTerminal
switch Shell { formats = shell.GetFormats(Shell)
case shell.BASH:
formats = &shellFormats{
escape: "\\[%s\\]",
linechange: "\\[\x1b[%d%s\\]",
left: "\\[\x1b[%dD\\]",
clearBelow: "\\[\x1b[0J\\]",
clearLine: "\\[\x1b[K\\]",
saveCursorPosition: "\\[\x1b7\\]",
restoreCursorPosition: "\\[\x1b8\\]",
title: "\\[\x1b]0;%s\007\\]",
hyperlinkStart: "\\[\x1b]8;;",
hyperlinkCenter: "\x1b\\\\\\]",
hyperlinkEnd: "\\[\x1b]8;;\x1b\\\\\\]",
osc99: "\\[\x1b]9;9;%s\x1b\\\\\\]",
osc7: "\\[\x1b]7;file://%s/%s\x1b\\\\\\]",
osc51: "\\[\x1b]51;A;%s@%s:%s\x1b\\\\\\]",
iTermPromptMark: "\\[$(iterm2_prompt_mark)\\]",
iTermCurrentDir: "\\[\x1b]1337;CurrentDir=%s\x07\\]",
iTermRemoteHost: "\\[\x1b]1337;RemoteHost=%s@%s\x07\\]",
escapeSequences: map[rune]rune{
96: 92, // backtick
92: 92, // backslash
},
}
case shell.ZSH, shell.TCSH:
formats = &shellFormats{
escape: "%%{%s%%}",
linechange: "%%{\x1b[%d%s%%}",
left: "%%{\x1b[%dD%%}",
clearBelow: "%{\x1b[0J%}",
clearLine: "%{\x1b[K%}",
saveCursorPosition: "%{\x1b7%}",
restoreCursorPosition: "%{\x1b8%}",
title: "%%{\x1b]0;%s\007%%}",
hyperlinkStart: "%{\x1b]8;;",
hyperlinkCenter: "\x1b\\%}",
hyperlinkEnd: "%{\x1b]8;;\x1b\\%}",
osc99: "%%{\x1b]9;9;%s\x1b\\%%}",
osc7: "%%{\x1b]7;file://%s/%s\x1b\\%%}",
osc51: "%%{\x1b]51;A%s@%s:%s\x1b\\%%}",
iTermPromptMark: "%{$(iterm2_prompt_mark)%}",
iTermCurrentDir: "%%{\x1b]1337;CurrentDir=%s\x07%%}",
iTermRemoteHost: "%%{\x1b]1337;RemoteHost=%s@%s\x07%%}",
}
default:
formats = &shellFormats{
escape: "%s",
linechange: "\x1b[%d%s",
left: "\x1b[%dD",
clearBelow: "\x1b[0J",
clearLine: "\x1b[K",
saveCursorPosition: "\x1b7",
restoreCursorPosition: "\x1b8",
title: "\x1b]0;%s\007",
// when in fish on Linux, it seems hyperlinks ending with \\ print a \
// unlike on macOS. However, this is a fish bug, so do not try to fix it here:
// https://github.com/JanDeDobbeleer/oh-my-posh/pull/3288#issuecomment-1369137068
hyperlinkStart: "\x1b]8;;",
hyperlinkCenter: "\x1b\\",
hyperlinkEnd: "\x1b]8;;\x1b\\",
osc99: "\x1b]9;9;%s\x1b\\",
osc7: "\x1b]7;file://%s/%s\x1b\\",
osc51: "\x1b]51;A%s@%s:%s\x1b\\",
iTermCurrentDir: "\x1b]1337;CurrentDir=%s\x07",
iTermRemoteHost: "\x1b]1337;RemoteHost=%s@%s\x07",
}
}
if Shell == shell.ZSH {
formats.escapeSequences = map[rune]rune{
96: 92, // backtick
37: 37, // %
}
}
} }
func getTerminalName() string { func getTerminalName() string {
@ -274,7 +173,7 @@ func ChangeLine(numberOfLines int) string {
numberOfLines = -numberOfLines numberOfLines = -numberOfLines
} }
return fmt.Sprintf(formats.linechange, numberOfLines, position) return fmt.Sprintf(formats.Linechange, numberOfLines, position)
} }
func Pwd(pwdType, userName, hostName, pwd string) string { func Pwd(pwdType, userName, hostName, pwd string) string {
@ -288,13 +187,13 @@ func Pwd(pwdType, userName, hostName, pwd string) string {
switch pwdType { switch pwdType {
case OSC7: case OSC7:
return fmt.Sprintf(formats.osc7, hostName, pwd) return fmt.Sprintf(formats.Osc7, hostName, pwd)
case OSC51: case OSC51:
return fmt.Sprintf(formats.osc51, userName, hostName, pwd) return fmt.Sprintf(formats.Osc51, userName, hostName, pwd)
case OSC99: case OSC99:
fallthrough fallthrough
default: default:
return fmt.Sprintf(formats.osc99, pwd) return fmt.Sprintf(formats.Osc99, pwd)
} }
} }
@ -303,7 +202,7 @@ func ClearAfter() string {
return "" return ""
} }
return formats.clearLine + formats.clearBelow return formats.ClearLine + formats.ClearBelow
} }
func FormatTitle(title string) string { func FormatTitle(title string) string {
@ -324,42 +223,42 @@ func FormatTitle(title string) string {
return "" return ""
} }
return fmt.Sprintf(formats.title, title) return fmt.Sprintf(formats.Title, title)
} }
func EscapeText(text string) string { func EscapeText(text string) string {
return fmt.Sprintf(formats.escape, text) return fmt.Sprintf(formats.Escape, text)
} }
func SaveCursorPosition() string { func SaveCursorPosition() string {
return formats.saveCursorPosition return formats.SaveCursorPosition
} }
func RestoreCursorPosition() string { func RestoreCursorPosition() string {
return formats.restoreCursorPosition return formats.RestoreCursorPosition
} }
func PromptStart() string { func PromptStart() string {
return fmt.Sprintf(formats.escape, "\x1b]133;A\007") return fmt.Sprintf(formats.Escape, "\x1b]133;A\007")
} }
func CommandStart() string { func CommandStart() string {
return fmt.Sprintf(formats.escape, "\x1b]133;B\007") return fmt.Sprintf(formats.Escape, "\x1b]133;B\007")
} }
func CommandFinished(code int, ignore bool) string { func CommandFinished(code int, ignore bool) string {
if ignore { if ignore {
return fmt.Sprintf(formats.escape, "\x1b]133;D\007") return fmt.Sprintf(formats.Escape, "\x1b]133;D\007")
} }
mark := fmt.Sprintf("\x1b]133;D;%d\007", code) mark := fmt.Sprintf("\x1b]133;D;%d\007", code)
return fmt.Sprintf(formats.escape, mark) return fmt.Sprintf(formats.Escape, mark)
} }
func LineBreak() string { func LineBreak() string {
cr := fmt.Sprintf(formats.left, 1000) cr := fmt.Sprintf(formats.Left, 1000)
lf := fmt.Sprintf(formats.linechange, 1, "B") lf := fmt.Sprintf(formats.Linechange, 1, "B")
return cr + lf return cr + lf
} }
@ -368,7 +267,7 @@ func StartProgress() string {
return "" return ""
} }
return fmt.Sprintf(formats.escape, startProgress) return fmt.Sprintf(formats.Escape, startProgress)
} }
func StopProgress() string { func StopProgress() string {
@ -376,7 +275,7 @@ func StopProgress() string {
return "" return ""
} }
return fmt.Sprintf(formats.escape, endProgress) return fmt.Sprintf(formats.Escape, endProgress)
} }
func Write(background, foreground, text string) { func Write(background, foreground, text string) {
@ -414,7 +313,7 @@ func Write(background, foreground, text string) {
// print the hyperlink part AFTER the coloring // print the hyperlink part AFTER the coloring
if match[ANCHOR] == hyperLinkStart { if match[ANCHOR] == hyperLinkStart {
isHyperlink = true isHyperlink = true
builder.WriteString(formats.hyperlinkStart) builder.WriteString(formats.HyperlinkStart)
} }
text = text[len(match[ANCHOR]):] text = text[len(match[ANCHOR]):]
@ -438,13 +337,13 @@ func Write(background, foreground, text string) {
case hyperLinkStart: case hyperLinkStart:
isHyperlink = true isHyperlink = true
i += len([]rune(match[ANCHOR])) - 1 i += len([]rune(match[ANCHOR])) - 1
builder.WriteString(formats.hyperlinkStart) builder.WriteString(formats.HyperlinkStart)
continue continue
case hyperLinkText: case hyperLinkText:
isHyperlink = false isHyperlink = false
i += len([]rune(match[ANCHOR])) - 1 i += len([]rune(match[ANCHOR])) - 1
hyperlinkTextPosition = i hyperlinkTextPosition = i
builder.WriteString(formats.hyperlinkCenter) builder.WriteString(formats.HyperlinkCenter)
continue continue
case hyperLinkTextEnd: case hyperLinkTextEnd:
// this implies there's no text in the hyperlink // this implies there's no text in the hyperlink
@ -456,7 +355,7 @@ func Write(background, foreground, text string) {
continue continue
case hyperLinkEnd: case hyperLinkEnd:
i += len([]rune(match[ANCHOR])) - 1 i += len([]rune(match[ANCHOR])) - 1
builder.WriteString(formats.hyperlinkEnd) builder.WriteString(formats.HyperlinkEnd)
continue continue
} }
@ -492,8 +391,8 @@ func writeEscapedAnsiString(text string) {
return return
} }
if len(formats.escape) != 0 { if len(formats.Escape) != 0 {
text = fmt.Sprintf(formats.escape, text) text = fmt.Sprintf(formats.Escape, text)
} }
builder.WriteString(text) builder.WriteString(text)
@ -514,7 +413,7 @@ func write(s rune) {
} }
if !Interactive { if !Interactive {
for special, escape := range formats.escapeSequences { for special, escape := range formats.EscapeSequences {
if s == special && lastRune != escape { if s == special && lastRune != escape {
builder.WriteRune(escape) builder.WriteRune(escape)
} }