fix: render newline correctly cross platform/shell

Powershell has an issue rendering multiline prompts when it comes to
PSReadline on MacOS. To mitigate that, we make it a multiline
prompt by moving the cursor all the way to the end. That way, PSReadline
believes this is still a one line prompt and everything works as
expected.

https://github.com/PowerShell/PowerShell/issues/3687
This commit is contained in:
Jan De Dobbeleer 2020-09-16 13:08:28 +02:00 committed by Jan De Dobbeleer
parent 5c4af19d90
commit 6fd9f0bdd9
2 changed files with 10 additions and 15 deletions

View file

@ -1,7 +1,6 @@
package main package main
import ( import (
"bytes"
"fmt" "fmt"
"regexp" "regexp"
@ -122,34 +121,31 @@ func (e *engine) lenWithoutANSI(str string) int {
return count return count
} }
func (e *engine) string() string { func (e *engine) render() {
var buffer bytes.Buffer
defer buffer.Reset()
for _, block := range e.settings.Blocks { for _, block := range e.settings.Blocks {
// if line break, append a line break // if line break, append a line break
if block.Type == LineBreak { if block.Type == LineBreak {
buffer.WriteString("\x1b[1B") fmt.Printf("\x1b[%dC ", 1000)
continue continue
} }
if block.LineOffset < 0 { if block.LineOffset < 0 {
buffer.WriteString(fmt.Sprintf("\x1b[%dF", -block.LineOffset)) fmt.Printf("\x1b[%dF", -block.LineOffset)
} else if block.LineOffset > 0 { } else if block.LineOffset > 0 {
buffer.WriteString(fmt.Sprintf("\x1b[%dB", block.LineOffset)) fmt.Printf("\x1b[%dB", block.LineOffset)
} }
switch block.Alignment { switch block.Alignment {
case Right: case Right:
buffer.WriteString(fmt.Sprintf("\x1b[%dC", 1000)) fmt.Printf("\x1b[%dC", 1000)
blockText := e.renderBlockSegments(block) blockText := e.renderBlockSegments(block)
buffer.WriteString(fmt.Sprintf("\x1b[%dD", e.lenWithoutANSI(blockText)+e.settings.RightSegmentOffset)) fmt.Printf("\x1b[%dD", e.lenWithoutANSI(blockText)+e.settings.RightSegmentOffset)
buffer.WriteString(blockText) fmt.Print(blockText)
default: default:
buffer.WriteString(e.renderBlockSegments(block)) fmt.Print(e.renderBlockSegments(block))
} }
} }
if e.settings.EndSpaceEnabled { if e.settings.EndSpaceEnabled {
buffer.WriteString(" ") fmt.Print(" ")
} }
return buffer.String()
} }
func (e *engine) reset() { func (e *engine) reset() {

View file

@ -45,6 +45,5 @@ func main() {
Buffer: new(bytes.Buffer), Buffer: new(bytes.Buffer),
}, },
} }
prompt := engine.string() engine.render()
fmt.Print(prompt)
} }