mirror of
https://github.com/JanDeDobbeleer/oh-my-posh.git
synced 2025-03-05 20:49:04 -08:00
feat(pwsh): transient prompt
This commit is contained in:
parent
7bb0c9ae0b
commit
7c72e76aff
|
@ -9,15 +9,17 @@ import TabItem from "@theme/TabItem";
|
|||
|
||||
## Tooltips
|
||||
|
||||
:::info
|
||||
Due to limitations (or not having found a way just yet) this feature only work in `zsh` and `powershell` for
|
||||
the time being.
|
||||
:::
|
||||
|
||||
Tooltips are segments that are rendered as a right aligned prompt while you're typing certain keywords.
|
||||
They behave similar to the other segments when it comes to how and when they are shown so you can tweak
|
||||
them to act and look like you want. The key difference is that they can be invoked using `tips` which are the
|
||||
commands you are typing. Due to the possibility of the use of an alias, you can define for which keyword
|
||||
the segment should be rendered.
|
||||
|
||||
Due to limitations (or not having found a way just yet) this feature only work for `zsh` and `powershell` at
|
||||
the time of writing.
|
||||
|
||||
### Configuration
|
||||
|
||||
You need to extend or create a custom theme with your tooltips. For example:
|
||||
|
@ -87,3 +89,65 @@ Restart your shell or reload `.zshrc` using `source ~/.zshrc` for the changes to
|
|||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Transient prompt
|
||||
|
||||
:::info
|
||||
This feature only works in `powershell` for the time being.
|
||||
:::
|
||||
|
||||
Transient prompt, when enabled, replaces the prompt with a simpler one to allow more screen real estate.
|
||||
You can use go [text/template][go-text-template] templates extended with [sprig][sprig] to enrich the text.
|
||||
Environment variables are available, just like the [`console_title_template`][console-title] functionality.
|
||||
|
||||
### Configuration
|
||||
|
||||
You need to extend or create a custom theme with your transient prompt. For example:
|
||||
|
||||
```json
|
||||
{
|
||||
"blocks": {
|
||||
...
|
||||
}
|
||||
"transient_prompt": {
|
||||
"background": "transparent",
|
||||
"foreground": "#ffffff",
|
||||
"template": "{{ .Shell }}> <#f7dc66>{{ .Command }}</>"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The configuration has the following properties:
|
||||
|
||||
- background: `string` [color][colors]
|
||||
- foreground: `string` [color][colors]
|
||||
- template: `string` - A go [text/template][go-text-template] template extended with [sprig][sprig] utilizing the
|
||||
properties below. Defaults to `{{ .Shell }}> <#f7dc66>{{ .Command }}</>`
|
||||
- vertical_offset: `int` - Move the prompt up or down x lines. For example `vertical_offset: 1` moves the prompt down one line, `vertical_offset: -1`
|
||||
moves it up one line. Useful when you have a multiline prompt. Defaults to `0`
|
||||
|
||||
#### Template Properties
|
||||
|
||||
- `.Command`: `string` - the shell command you typed
|
||||
- `.Root`: `boolean` - is the current user root/admin or not
|
||||
- `.Path`: `string` - the current working directory
|
||||
- `.Folder`: `string` - the current working folder
|
||||
- `.Shell`: `string` - the current shell name
|
||||
- `.User`: `string` - the current user name
|
||||
- `.Host`: `string` - the host name
|
||||
- `.Env.VarName`: `string` - Any environment variable where `VarName` is the environment variable name
|
||||
|
||||
### Enable the feature
|
||||
|
||||
Import/invoke Oh My Posh in your `$PROFILE` and add the following line below:
|
||||
|
||||
```pwsh
|
||||
Enable-PoshTransientPrompt
|
||||
```
|
||||
|
||||
Restart your shell or reload your `$PROFILE` using `. $PROFILE` for the changes to take effect.
|
||||
|
||||
[go-text-template]: https://golang.org/pkg/text/template/
|
||||
[sprig]: https://masterminds.github.io/sprig/
|
||||
[console-title]: /docs/configure#console-title-template
|
||||
[colors]: /docs/configure#colors
|
||||
|
|
|
@ -319,7 +319,26 @@ Note for Windows users: Windows directory separators should be specified as 4 ba
|
|||
]
|
||||
```
|
||||
|
||||
#### Colors
|
||||
### Colors
|
||||
|
||||
#### Standard colors
|
||||
|
||||
Oh My Posh mainly supports three different color types being
|
||||
|
||||
- Typical [hex colors][hexcolors] (for example `#CB4B16`).
|
||||
- The `transparent` keyword which can be used to create either a transparent foreground override
|
||||
or transparent background color using the segment's foreground property.
|
||||
- 16 [ANSI color names][ansicolors].
|
||||
|
||||
These include 8 basic ANSI colors and `default`:
|
||||
|
||||
`black` `red` `green` `yellow` `blue` `magenta` `cyan` `white` `default`
|
||||
|
||||
as well as 8 extended ANSI colors:
|
||||
|
||||
`darkGray` `lightRed` `lightGreen` `lightYellow` `lightBlue` `lightMagenta` `lightCyan` `lightWhite`
|
||||
|
||||
#### Color overrides
|
||||
|
||||
You have the ability to override the foreground and/or background color for text in any property that accepts it.
|
||||
The syntax is custom but should be rather straighforward:
|
||||
|
@ -345,21 +364,6 @@ To change *only* the background color, just omit the first color from the above
|
|||
"prefix": "<,#FFFFFF>┏[</>",
|
||||
```
|
||||
|
||||
Oh My Posh mainly supports three different color types being
|
||||
|
||||
- Typical [hex colors][hexcolors] (for example `#CB4B16`).
|
||||
- The `transparent` keyword which can be used to create either a transparent foreground override
|
||||
or transparent background color using the segment's foreground property.
|
||||
- 16 [ANSI color names][ansicolors].
|
||||
|
||||
These include 8 basic ANSI colors and `default`:
|
||||
|
||||
`black` `red` `green` `yellow` `blue` `magenta` `cyan` `white` `default`
|
||||
|
||||
as well as 8 extended ANSI colors:
|
||||
|
||||
`darkGray` `lightRed` `lightGreen` `lightYellow` `lightBlue` `lightMagenta` `lightCyan` `lightWhite`
|
||||
|
||||
### Text decorations
|
||||
|
||||
You can make use of the following syntax to decorate text:
|
||||
|
|
|
@ -49,3 +49,5 @@ properties below. Only used when a value is set, making the above properties obs
|
|||
- `POSH_SESSION_DEFAULT_USER` - used to override the hardcoded `default_user_name` property
|
||||
|
||||
[colors]: /docs/configure#colors
|
||||
[go-text-template]: https://golang.org/pkg/text/template/
|
||||
[sprig]: https://masterminds.github.io/sprig/
|
||||
|
|
|
@ -71,3 +71,6 @@ Show the current timestamp.
|
|||
- StampMilli = "Jan _2 15:04:05.000"
|
||||
- StampMicro = "Jan _2 15:04:05.000000"
|
||||
- StampNano = "Jan _2 15:04:05.000000000"
|
||||
|
||||
[go-text-template]: https://golang.org/pkg/text/template/
|
||||
[sprig]: https://masterminds.github.io/sprig/
|
||||
|
|
24
src/ansi.go
24
src/ansi.go
|
@ -39,10 +39,10 @@ func (a *ansiUtils) init(shell string) {
|
|||
switch shell {
|
||||
case zsh:
|
||||
a.linechange = "%%{\x1b[%d%s%%}"
|
||||
a.left = "%%{\x1b[%dC%%}"
|
||||
a.right = "%%{\x1b[%dD%%}"
|
||||
a.right = "%%{\x1b[%dC%%}"
|
||||
a.left = "%%{\x1b[%dD%%}"
|
||||
a.creset = "%{\x1b[0m%}"
|
||||
a.clearEOL = "%{\x1b[K%}"
|
||||
a.clearEOL = "%{\x1b[0J%}"
|
||||
a.saveCursorPosition = "%{\x1b7%}"
|
||||
a.restoreCursorPosition = "%{\x1b8%}"
|
||||
a.title = "%%{\x1b]0;%s\007%%}"
|
||||
|
@ -59,10 +59,10 @@ func (a *ansiUtils) init(shell string) {
|
|||
a.strikethrough = "%%{\x1b[9m%%}%s%%{\x1b[29m%%}"
|
||||
case bash:
|
||||
a.linechange = "\\[\x1b[%d%s\\]"
|
||||
a.left = "\\[\x1b[%dC\\]"
|
||||
a.right = "\\[\x1b[%dD\\]"
|
||||
a.right = "\\[\x1b[%dC\\]"
|
||||
a.left = "\\[\x1b[%dD\\]"
|
||||
a.creset = "\\[\x1b[0m\\]"
|
||||
a.clearEOL = "\\[\x1b[K\\]"
|
||||
a.clearEOL = "\\[\x1b[0J\\]"
|
||||
a.saveCursorPosition = "\\[\x1b7\\]"
|
||||
a.restoreCursorPosition = "\\[\x1b8\\]"
|
||||
a.title = "\\[\x1b]0;%s\007\\]"
|
||||
|
@ -79,10 +79,10 @@ func (a *ansiUtils) init(shell string) {
|
|||
a.strikethrough = "\\[\x1b[9m\\]%s\\[\x1b[29m\\]"
|
||||
default:
|
||||
a.linechange = "\x1b[%d%s"
|
||||
a.left = "\x1b[%dC"
|
||||
a.right = "\x1b[%dD"
|
||||
a.right = "\x1b[%dC"
|
||||
a.left = "\x1b[%dD"
|
||||
a.creset = "\x1b[0m"
|
||||
a.clearEOL = "\x1b[K"
|
||||
a.clearEOL = "\x1b[0J"
|
||||
a.saveCursorPosition = "\x1b7"
|
||||
a.restoreCursorPosition = "\x1b8"
|
||||
a.title = "\x1b]0;%s\007"
|
||||
|
@ -153,12 +153,16 @@ func (a *ansiUtils) formatText(text string) string {
|
|||
}
|
||||
|
||||
func (a *ansiUtils) carriageForward() string {
|
||||
return fmt.Sprintf(a.right, 1000)
|
||||
}
|
||||
|
||||
func (a *ansiUtils) carriageBackward() string {
|
||||
return fmt.Sprintf(a.left, 1000)
|
||||
}
|
||||
|
||||
func (a *ansiUtils) getCursorForRightWrite(text string, offset int) string {
|
||||
strippedLen := a.lenWithoutANSI(text) + -offset
|
||||
return fmt.Sprintf(a.right, strippedLen)
|
||||
return fmt.Sprintf(a.left, strippedLen)
|
||||
}
|
||||
|
||||
func (a *ansiUtils) changeLine(numberOfLines int) string {
|
||||
|
|
|
@ -28,6 +28,14 @@ type Config struct {
|
|||
TerminalBackground string `config:"terminal_background"`
|
||||
Blocks []*Block `config:"blocks"`
|
||||
Tooltips []*Segment `config:"tooltips"`
|
||||
TransientPrompt *TransientPrompt `config:"transient_prompt"`
|
||||
}
|
||||
|
||||
type TransientPrompt struct {
|
||||
Template string `config:"template"`
|
||||
Background string `config:"background"`
|
||||
Foreground string `config:"foreground"`
|
||||
VerticalOffset int `config:"vertical_offset"`
|
||||
}
|
||||
|
||||
const (
|
||||
|
@ -80,6 +88,11 @@ func loadConfig(env environmentInfo) (*Config, error) {
|
|||
return nil, errors.New("INVALID CONFIG")
|
||||
}
|
||||
|
||||
// initialize default values
|
||||
if cfg.TransientPrompt == nil {
|
||||
cfg.TransientPrompt = &TransientPrompt{}
|
||||
}
|
||||
|
||||
return &cfg, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -40,28 +40,11 @@ func (t *consoleTitle) getConsoleTitle() string {
|
|||
}
|
||||
|
||||
func (t *consoleTitle) getTemplateText() string {
|
||||
context := make(map[string]interface{})
|
||||
|
||||
context["Root"] = t.env.isRunningAsRoot()
|
||||
context["Path"] = t.getPwd()
|
||||
context["Folder"] = base(t.getPwd(), t.env)
|
||||
context["Shell"] = t.env.getShellName()
|
||||
context["User"] = t.env.getCurrentUser()
|
||||
context["Host"] = ""
|
||||
if host, err := t.env.getHostName(); err == nil {
|
||||
context["Host"] = host
|
||||
}
|
||||
|
||||
template := &textTemplate{
|
||||
Template: t.config.ConsoleTitleTemplate,
|
||||
Context: context,
|
||||
Env: t.env,
|
||||
}
|
||||
text, err := template.render()
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
return text
|
||||
return template.renderPlainContextTemplate(nil)
|
||||
}
|
||||
|
||||
func (t *consoleTitle) getPwd() string {
|
||||
|
|
|
@ -217,3 +217,23 @@ func (e *engine) renderTooltip(tip string) string {
|
|||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (e *engine) renderTransientPrompt(command string) string {
|
||||
promptTemplate := e.config.TransientPrompt.Template
|
||||
if len(promptTemplate) == 0 {
|
||||
promptTemplate = "{{ .Shell }}> <#f7dc66>{{ .Command }}</>"
|
||||
}
|
||||
template := &textTemplate{
|
||||
Template: promptTemplate,
|
||||
Env: e.env,
|
||||
}
|
||||
context := make(map[string]interface{})
|
||||
context["Command"] = command
|
||||
prompt := template.renderPlainContextTemplate(context)
|
||||
e.colorWriter.write(e.config.TransientPrompt.Background, e.config.TransientPrompt.Foreground, prompt)
|
||||
transientPrompt := e.ansi.carriageBackward()
|
||||
if e.config.TransientPrompt.VerticalOffset != 0 {
|
||||
transientPrompt += e.ansi.changeLine(e.config.TransientPrompt.VerticalOffset)
|
||||
}
|
||||
return transientPrompt + e.colorWriter.string() + e.ansi.clearEOL
|
||||
}
|
||||
|
|
|
@ -192,11 +192,24 @@ function global:Enable-PoshTooltips {
|
|||
$position = $host.UI.RawUI.CursorPosition
|
||||
$omp = "::OMP::"
|
||||
$config, $cleanPWD, $cleanPSWD = Get-PoshContext
|
||||
$tooltip = $null
|
||||
$command = $null
|
||||
$cursor = $null
|
||||
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$tooltip, [ref]$cursor)
|
||||
$standardOut = @(&$omp --pwd="$cleanPWD" --pswd="$cleanPSWD" --config="$config" --tooltip="$tooltip" 2>&1)
|
||||
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$command, [ref]$cursor)
|
||||
$standardOut = @(&$omp --pwd="$cleanPWD" --pswd="$cleanPSWD" --config="$config" --command="$command" 2>&1)
|
||||
Write-Host $standardOut -NoNewline
|
||||
$host.UI.RawUI.CursorPosition = $position
|
||||
}
|
||||
}
|
||||
|
||||
function global:Enable-PoshTransientPrompt {
|
||||
Set-PSReadlineKeyHandler -Key Enter -ScriptBlock {
|
||||
$command = $null
|
||||
$cursor = $null
|
||||
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$command, [ref]$cursor)
|
||||
$omp = "::OMP::"
|
||||
$config, $cleanPWD, $cleanPSWD = Get-PoshContext
|
||||
$standardOut = @(&$omp --pwd="$cleanPWD" --pswd="$cleanPSWD" --config="$config" --command="$command" --print-transient 2>&1)
|
||||
Write-Host $standardOut -NoNewline
|
||||
[Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ function self-insert() {
|
|||
zle .self-insert
|
||||
return
|
||||
fi
|
||||
tooltip=$(::OMP:: --config $POSH_THEME --shell zsh --tooltip $BUFFER)
|
||||
tooltip=$(::OMP:: --config $POSH_THEME --shell zsh --command $BUFFER)
|
||||
# ignore an empty tooltip
|
||||
if [[ ! -z "$tooltip" ]]; then
|
||||
RPROMPT=$tooltip
|
||||
|
|
61
src/main.go
61
src/main.go
|
@ -37,27 +37,28 @@ const (
|
|||
)
|
||||
|
||||
type args struct {
|
||||
ErrorCode *int
|
||||
PrintConfig *bool
|
||||
ConfigFormat *string
|
||||
PrintShell *bool
|
||||
Config *string
|
||||
Shell *string
|
||||
PWD *string
|
||||
PSWD *string
|
||||
Version *bool
|
||||
Debug *bool
|
||||
ExecutionTime *float64
|
||||
Millis *bool
|
||||
Eval *bool
|
||||
Init *bool
|
||||
PrintInit *bool
|
||||
ExportPNG *bool
|
||||
Author *string
|
||||
CursorPadding *int
|
||||
RPromptOffset *int
|
||||
StackCount *int
|
||||
ToolTip *string
|
||||
ErrorCode *int
|
||||
PrintConfig *bool
|
||||
ConfigFormat *string
|
||||
PrintShell *bool
|
||||
Config *string
|
||||
Shell *string
|
||||
PWD *string
|
||||
PSWD *string
|
||||
Version *bool
|
||||
Debug *bool
|
||||
ExecutionTime *float64
|
||||
Millis *bool
|
||||
Eval *bool
|
||||
Init *bool
|
||||
PrintInit *bool
|
||||
ExportPNG *bool
|
||||
Author *string
|
||||
CursorPadding *int
|
||||
RPromptOffset *int
|
||||
StackCount *int
|
||||
Command *string
|
||||
PrintTransient *bool
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
@ -142,10 +143,14 @@ func main() {
|
|||
"stack-count",
|
||||
0,
|
||||
"The current location stack count"),
|
||||
ToolTip: flag.String(
|
||||
"tooltip",
|
||||
Command: flag.String(
|
||||
"command",
|
||||
"",
|
||||
"Render a tooltip based on the string value"),
|
||||
"Render a tooltip based on the command value"),
|
||||
PrintTransient: flag.Bool(
|
||||
"print-transient",
|
||||
false,
|
||||
"Print the transient prompt"),
|
||||
}
|
||||
flag.Parse()
|
||||
env := &environment{}
|
||||
|
@ -200,8 +205,12 @@ func main() {
|
|||
fmt.Print(engine.debug())
|
||||
return
|
||||
}
|
||||
if len(*args.ToolTip) != 0 {
|
||||
fmt.Print(engine.renderTooltip(*args.ToolTip))
|
||||
if *args.PrintTransient {
|
||||
fmt.Print(engine.renderTransientPrompt(*args.Command))
|
||||
return
|
||||
}
|
||||
if len(*args.Command) != 0 {
|
||||
fmt.Print(engine.renderTooltip(*args.Command))
|
||||
return
|
||||
}
|
||||
prompt := engine.render()
|
||||
|
|
|
@ -24,6 +24,29 @@ type textTemplate struct {
|
|||
Env environmentInfo
|
||||
}
|
||||
|
||||
func (t *textTemplate) renderPlainContextTemplate(context map[string]interface{}) string {
|
||||
if context == nil {
|
||||
context = make(map[string]interface{})
|
||||
}
|
||||
context["Root"] = t.Env.isRunningAsRoot()
|
||||
pwd := t.Env.getcwd()
|
||||
pwd = strings.Replace(pwd, t.Env.homeDir(), "~", 1)
|
||||
context["Path"] = pwd
|
||||
context["Folder"] = base(pwd, t.Env)
|
||||
context["Shell"] = t.Env.getShellName()
|
||||
context["User"] = t.Env.getCurrentUser()
|
||||
context["Host"] = ""
|
||||
if host, err := t.Env.getHostName(); err == nil {
|
||||
context["Host"] = host
|
||||
}
|
||||
t.Context = context
|
||||
text, err := t.render()
|
||||
if err != nil {
|
||||
return err.Error()
|
||||
}
|
||||
return text
|
||||
}
|
||||
|
||||
func (t *textTemplate) render() (string, error) {
|
||||
tmpl, err := template.New("title").Funcs(sprig.TxtFuncMap()).Parse(t.Template)
|
||||
if err != nil {
|
||||
|
|
|
@ -1589,6 +1589,26 @@
|
|||
},
|
||||
"required": ["tips"]
|
||||
}
|
||||
},
|
||||
"transient_prompt": {
|
||||
"type": "object",
|
||||
"title": "Transient Prompt Settings",
|
||||
"description": "https://ohmyposh.dev/docs/beta#transient-prompt",
|
||||
"default": {},
|
||||
"properties": {
|
||||
"template": {
|
||||
"type": "string",
|
||||
"title": "Transient Prompt Template",
|
||||
"default": "{{ .Shell }}> <#f7dc66>{{ .Command }}</>"
|
||||
},
|
||||
"vertical_offset": {
|
||||
"type": "integer",
|
||||
"title": "Transient Prompt vertical offset",
|
||||
"default": 0
|
||||
},
|
||||
"background": { "$ref": "#/definitions/color" },
|
||||
"foreground": { "$ref": "#/definitions/color" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue