feat: powershell rprompt support

This commit is contained in:
TravisTX 2020-12-15 06:58:15 -07:00 committed by Jan De Dobbeleer
parent 3ca2cb5ef3
commit 85b1fc2662
6 changed files with 49 additions and 16 deletions

3
.gitignore vendored
View file

@ -145,3 +145,6 @@ dist
.history
# End of https://www.toptal.com/developers/gitignore/api/node,go,visualstudiocode
# linux binary
/oh-my-posh3

View file

@ -30,12 +30,14 @@ func lenWithoutANSI(text, shell string) int {
}
type formats struct {
linechange string
left string
right string
title string
creset string
clearOEL string
linechange string
left string
right string
title string
creset string
clearOEL string
saveCursorPosition string
restoreCursorPosition string
}
// AnsiRenderer exposes functionality using ANSI
@ -46,8 +48,10 @@ type AnsiRenderer struct {
}
const (
zsh = "zsh"
bash = "bash"
zsh = "zsh"
bash = "bash"
pwsh = "pwsh"
powershell5 = "powershell"
)
func (r *AnsiRenderer) init(shell string) {
@ -61,6 +65,8 @@ func (r *AnsiRenderer) init(shell string) {
r.formats.title = "%%{\033]0;%s\007%%}"
r.formats.creset = "%{\x1b[0m%}"
r.formats.clearOEL = "%{\x1b[K%}"
r.formats.saveCursorPosition = "%{\x1b7%}"
r.formats.restoreCursorPosition = "%{\x1b8%}"
case bash:
r.formats.linechange = "\\[\x1b[%d%s\\]"
r.formats.left = "\\[\x1b[%dC\\]"
@ -68,6 +74,8 @@ func (r *AnsiRenderer) init(shell string) {
r.formats.title = "\\[\033]0;%s\007\\]"
r.formats.creset = "\\[\x1b[0m\\]"
r.formats.clearOEL = "\\[\x1b[K\\]"
r.formats.saveCursorPosition = "\\[\x1b7\\]"
r.formats.restoreCursorPosition = "\\[\x1b8\\]"
default:
r.formats.linechange = "\x1b[%d%s"
r.formats.left = "\x1b[%dC"
@ -75,6 +83,8 @@ func (r *AnsiRenderer) init(shell string) {
r.formats.title = "\033]0;%s\007"
r.formats.creset = "\x1b[0m"
r.formats.clearOEL = "\x1b[K"
r.formats.saveCursorPosition = "\x1b7"
r.formats.restoreCursorPosition = "\x1b8"
}
}
@ -116,3 +126,11 @@ func (r *AnsiRenderer) clearEOL() {
func (r *AnsiRenderer) string() string {
return r.buffer.String()
}
func (r *AnsiRenderer) saveCursorPosition() {
r.buffer.WriteString(r.formats.saveCursorPosition)
}
func (r *AnsiRenderer) restoreCursorPosition() {
r.buffer.WriteString(r.formats.restoreCursorPosition)
}

View file

@ -67,7 +67,7 @@ boxes with question marks, [set up your terminal][setupterm] to use a supported
Let's take a closer look at what defines a block.
- type: `prompt` | `newline` | `rprompt`
- type: `prompt` | `rprompt` | `newline`
- alignment: `left` | `right`
- vertical_offset: `int`
- horizontal_offset: `int`
@ -75,9 +75,13 @@ Let's take a closer look at what defines a block.
### Type
Tells the engine what to do with the block. There are three options, either it renders one or more segments,
inserts a newline to start the next block on a new line or sets a block as the `RPROMPT` when on [ZSH][rprompt].
New line blocks require no additional configuration other than the `type`.
Tells the engine what to do with the block. There are three options:
- `prompt` renders one or more segments
- `rprompt` renders one or more segments aligned to the right of the cursor. Only one `rprompt` block is permitted.
Supported on [ZSH][rprompt] and Powershell.
- `newline` inserts a new line to start the next block on a new line. `newline` blocks require no additional
configuration other than the `type`.
### Alignment

View file

@ -168,11 +168,19 @@ func (e *engine) render() {
func (e *engine) write() {
if *e.env.getArgs().Eval {
fmt.Printf("PS1=\"%s\"", e.renderer.string())
if e.rprompt != "" && e.env.getShellName() == zsh {
if e.env.getShellName() == zsh {
fmt.Printf("\nRPROMPT=\"%s\"", e.rprompt)
}
return
}
if e.rprompt != "" && (e.env.getShellName() == pwsh || e.env.getShellName() == powershell5) {
e.renderer.saveCursorPosition()
e.renderer.carriageForward()
e.renderer.setCursorForRightWrite(e.rprompt, 0)
e.renderer.print(e.rprompt)
e.renderer.restoreCursorPosition()
}
fmt.Print(e.renderer.string())
}

View file

@ -28,7 +28,7 @@ const (
Prompt BlockType = "prompt"
// LineBreak creates a line break in the prompt
LineBreak BlockType = "newline"
// RPrompt a right aligned prompt in ZSH
// RPrompt a right aligned prompt in ZSH and Powershell
RPrompt BlockType = "rprompt"
// Left aligns left
Left BlockAlignment = "left"

View file

@ -51,7 +51,7 @@
},
"then": {
"required": ["type", "segments"],
"title": "RPrompt definition, contains 1 or more segments to render in ZSH RPROMPT"
"title": "RPrompt definition, contains 1 or more segments to render to the right of the cursor"
}
}
],
@ -60,7 +60,7 @@
"type": "string",
"title": "Block type",
"description": "https://ohmyposh.dev/docs/configure#type",
"enum": ["prompt", "newline", "rprompt"],
"enum": ["prompt", "rprompt", "newline"],
"default": "prompt"
},
"alignment": {