feat: support osc9;9

resolves #409
This commit is contained in:
Jan De Dobbeleer 2021-02-14 14:09:43 +01:00 committed by Jan De Dobbeleer
parent 9457be3990
commit 860eeb478a
3 changed files with 20 additions and 11 deletions

View file

@ -23,6 +23,7 @@ type ansiFormats struct {
escapeLeft string escapeLeft string
escapeRight string escapeRight string
hyperlink string hyperlink string
osc99 string
} }
func (a *ansiFormats) init(shell string) { func (a *ansiFormats) init(shell string) {
@ -43,6 +44,7 @@ func (a *ansiFormats) init(shell string) {
a.escapeLeft = "%{" a.escapeLeft = "%{"
a.escapeRight = "%}" a.escapeRight = "%}"
a.hyperlink = "%%{\x1b]8;;%s\x1b\\%%}%s%%{\x1b]8;;\x1b\\%%}" a.hyperlink = "%%{\x1b]8;;%s\x1b\\%%}%s%%{\x1b]8;;\x1b\\%%}"
a.osc99 = "%%{\x1b]9;9;%s\x1b7%%}"
case bash: case bash:
a.linechange = "\\[\x1b[%d%s\\]" a.linechange = "\\[\x1b[%d%s\\]"
a.left = "\\[\x1b[%dC\\]" a.left = "\\[\x1b[%dC\\]"
@ -58,6 +60,7 @@ func (a *ansiFormats) init(shell string) {
a.escapeLeft = "\\[" a.escapeLeft = "\\["
a.escapeRight = "\\]" a.escapeRight = "\\]"
a.hyperlink = "\\[\x1b]8;;%s\x1b\\\\\\]%s\\[\x1b]8;;\x1b\\\\\\]" a.hyperlink = "\\[\x1b]8;;%s\x1b\\\\\\]%s\\[\x1b]8;;\x1b\\\\\\]"
a.osc99 = "\\[\x1b]9;9;%s\x1b7\\]"
default: default:
a.linechange = "\x1b[%d%s" a.linechange = "\x1b[%d%s"
a.left = "\x1b[%dC" a.left = "\x1b[%dC"
@ -73,6 +76,7 @@ func (a *ansiFormats) init(shell string) {
a.escapeLeft = "" a.escapeLeft = ""
a.escapeRight = "" a.escapeRight = ""
a.hyperlink = "\x1b]8;;%s\x1b\\%s\x1b]8;;\x1b\\" a.hyperlink = "\x1b]8;;%s\x1b\\%s\x1b]8;;\x1b\\"
a.osc99 = "\x1b]9;9;%s\x1b7"
} }
} }

View file

@ -33,7 +33,7 @@ func (r *AnsiRenderer) creset() {
r.builder.WriteString(r.formats.creset) r.builder.WriteString(r.formats.creset)
} }
func (r *AnsiRenderer) print(text string) { func (r *AnsiRenderer) write(text string) {
r.builder.WriteString(text) r.builder.WriteString(text)
// Due to a bug in Powershell, the end of the line needs to be cleared. // Due to a bug in Powershell, the end of the line needs to be cleared.
// If this doesn't happen, the portion after the prompt gets colored in the background // If this doesn't happen, the portion after the prompt gets colored in the background
@ -55,3 +55,7 @@ func (r *AnsiRenderer) saveCursorPosition() {
func (r *AnsiRenderer) restoreCursorPosition() { func (r *AnsiRenderer) restoreCursorPosition() {
r.builder.WriteString(r.formats.restoreCursorPosition) r.builder.WriteString(r.formats.restoreCursorPosition)
} }
func (r *AnsiRenderer) osc99(pwd string) {
r.builder.WriteString(fmt.Sprintf(r.formats.osc99, pwd))
}

View file

@ -138,7 +138,7 @@ func (e *engine) render() {
// if line break, append a line break // if line break, append a line break
switch block.Type { switch block.Type {
case LineBreak: case LineBreak:
e.renderer.print("\n") e.renderer.write("\n")
case Prompt: case Prompt:
if block.VerticalOffset != 0 { if block.VerticalOffset != 0 {
e.renderer.changeLine(block.VerticalOffset) e.renderer.changeLine(block.VerticalOffset)
@ -148,29 +148,30 @@ func (e *engine) render() {
e.renderer.carriageForward() e.renderer.carriageForward()
blockText := e.renderBlockSegments(block) blockText := e.renderBlockSegments(block)
e.renderer.setCursorForRightWrite(blockText, block.HorizontalOffset) e.renderer.setCursorForRightWrite(blockText, block.HorizontalOffset)
e.renderer.print(blockText) e.renderer.write(blockText)
case Left: case Left:
e.renderer.print(e.renderBlockSegments(block)) e.renderer.write(e.renderBlockSegments(block))
} }
case RPrompt: case RPrompt:
e.rprompt = e.renderBlockSegments(block) e.rprompt = e.renderBlockSegments(block)
} }
} }
if e.settings.ConsoleTitle { if e.settings.ConsoleTitle {
e.renderer.print(e.consoleTitle.getConsoleTitle()) e.renderer.write(e.consoleTitle.getConsoleTitle())
} }
e.renderer.creset() e.renderer.creset()
if e.settings.FinalSpace { if e.settings.FinalSpace {
e.renderer.print(" ") e.renderer.write(" ")
} }
e.write() e.renderer.osc99(e.env.getcwd())
e.print()
} }
// debug will loop through your config file and output the timings for each segments // debug will loop through your config file and output the timings for each segments
func (e *engine) debug() { func (e *engine) debug() {
var segmentTimings []SegmentTiming var segmentTimings []SegmentTiming
largestSegmentNameLength := 0 largestSegmentNameLength := 0
e.renderer.print("\n\x1b[1mHere are the timings of segments in your prompt:\x1b[0m\n\n") e.renderer.write("\n\x1b[1mHere are the timings of segments in your prompt:\x1b[0m\n\n")
// console title timing // console title timing
start := time.Now() start := time.Now()
@ -228,12 +229,12 @@ func (e *engine) debug() {
duration += segment.stringDuration.Milliseconds() duration += segment.stringDuration.Milliseconds()
} }
segmentName := fmt.Sprintf("%s(%t)", segment.name, segment.enabled) segmentName := fmt.Sprintf("%s(%t)", segment.name, segment.enabled)
e.renderer.print(fmt.Sprintf("%-*s - %3d ms - %s\n", largestSegmentNameLength, segmentName, duration, segment.stringValue)) e.renderer.write(fmt.Sprintf("%-*s - %3d ms - %s\n", largestSegmentNameLength, segmentName, duration, segment.stringValue))
} }
fmt.Print(e.renderer.string()) fmt.Print(e.renderer.string())
} }
func (e *engine) write() { func (e *engine) print() {
switch e.env.getShellName() { switch e.env.getShellName() {
case zsh: case zsh:
if *e.env.getArgs().Eval { if *e.env.getArgs().Eval {
@ -246,7 +247,7 @@ func (e *engine) write() {
e.renderer.saveCursorPosition() e.renderer.saveCursorPosition()
e.renderer.carriageForward() e.renderer.carriageForward()
e.renderer.setCursorForRightWrite(e.rprompt, 0) e.renderer.setCursorForRightWrite(e.rprompt, 0)
e.renderer.print(e.rprompt) e.renderer.write(e.rprompt)
e.renderer.restoreCursorPosition() e.renderer.restoreCursorPosition()
} }
} }