feat(pwsh): support PromptText

This commit is contained in:
Jan De Dobbeleer 2022-02-19 16:49:26 +01:00 committed by Jan De Dobbeleer
parent 3d4fc5b6dd
commit cb70ed4b41
9 changed files with 193 additions and 42 deletions

View file

@ -0,0 +1,86 @@
---
id: config-line-error
title: Line error
sidebar_label: Line error
---
:::info
This feature only works in `powershell` for the time being.
:::
Line error, when enabled, replaces the last part of the prompt when the text entered is invalid. It leverages
[PSReadLine's][psreadline] `-PromptText` setting by adding two distinct prompts. One for a valid line,
and one for when there's an error. As PSReadLine will rewrite the last part of
your prompt with the value of either based on the line's context, you will need to make sure everything
is compatible with your config as **these values are only set once** on shell start.
There are two config settings you need to tweak:
- `valid_line`: displays when the line is valid (again)
- `error_line`: displays when the line is faulty
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 prompt overrides. For example:
```json
{
"$schema": "https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/schema.json",
"blocks": {
...
}
"valid_line": {
"background": "transparent",
"foreground": "#ffffff",
"template": "<#e0def4,#286983>\uf42e </><#286983,transparent>\ue0b4</> "
},
"error_line": {
"background": "transparent",
"foreground": "#ffffff",
"template": "<#eb6f92,#286983>\ue009 </><#286983,transparent>\ue0b4</> "
}
}
```
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 ` `
## Template ([info][templates])
- `.Root`: `boolean` - is the current user root/admin or not
- `.PWD`: `string` - the current working directory
- `.Folder`: `string` - the current working folder
- `.Shell`: `string` - the current shell name
- `.UserName`: `string` - the current user name
- `.HostName`: `string` - the host name
- `.Env.VarName`: `string` - Any environment variable where `VarName` is the environment variable name
## Enable the feature
Invoke Oh My Posh in your `$PROFILE` and add the following line below.
```powershell
oh-my-posh --init --shell pwsh --config $env:POSH_THEMES_PATH/jandedobbeleer.omp.json | Invoke-Expression
// highlight-start
Enable-PoshLineError
// highlight-end
```
:::caution
If you import **PSReadLine** separately, make sure to import it before the `Enable-PoshLineError` command.
:::
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/config-title#console-title-template
[psreadline]: https://github.com/PowerShell/PSReadLine
[templates]: /docs/config-templates

View file

@ -118,3 +118,4 @@ Restart your shell or reload `.zshrc` using `source ~/.zshrc` for the changes to
[console-title]: /docs/config-title#console-title-template
[sprig]: https://masterminds.github.io/sprig/
[clink]: https://chrisant996.github.io/clink/
[templates]: /docs/config-templates

View file

@ -27,6 +27,7 @@ module.exports = {
"config-colors",
"config-templates",
"config-transient",
"config-line-error",
"config-tooltips",
"config-fonts",
],

View file

@ -30,17 +30,19 @@ const (
// Config holds all the theme for rendering the prompt
type Config struct {
Version int `json:"version"`
FinalSpace bool `json:"final_space,omitempty"`
OSC99 bool `json:"osc99,omitempty"`
ConsoleTitle bool `json:"console_title,omitempty"`
ConsoleTitleStyle console.Style `json:"console_title_style,omitempty"`
ConsoleTitleTemplate string `json:"console_title_template,omitempty"`
TerminalBackground string `json:"terminal_background,omitempty"`
Blocks []*Block `json:"blocks,omitempty"`
Tooltips []*Segment `json:"tooltips,omitempty"`
TransientPrompt *TransientPrompt `json:"transient_prompt,omitempty"`
Palette color.Palette `json:"palette,omitempty"`
Version int `json:"version"`
FinalSpace bool `json:"final_space,omitempty"`
OSC99 bool `json:"osc99,omitempty"`
ConsoleTitle bool `json:"console_title,omitempty"`
ConsoleTitleStyle console.Style `json:"console_title_style,omitempty"`
ConsoleTitleTemplate string `json:"console_title_template,omitempty"`
TerminalBackground string `json:"terminal_background,omitempty"`
Blocks []*Block `json:"blocks,omitempty"`
Tooltips []*Segment `json:"tooltips,omitempty"`
TransientPrompt *ExtraPrompt `json:"transient_prompt,omitempty"`
ValidLine *ExtraPrompt `json:"valid_line,omitempty"`
ErrorLine *ExtraPrompt `json:"error_line,omitempty"`
Palette color.Palette `json:"palette,omitempty"`
format string
origin string
@ -55,7 +57,7 @@ func (cfg *Config) MakeColors(env environment.Environment) color.AnsiColors {
return color.MakeColors(cfg.Palette, !cacheDisabled)
}
type TransientPrompt struct {
type ExtraPrompt struct {
Template string `json:"template,omitempty"`
Background string `json:"background,omitempty"`
Foreground string `json:"foreground,omitempty"`
@ -119,7 +121,7 @@ func loadConfig(env environment.Environment) *Config {
// initialize default values
if cfg.TransientPrompt == nil {
cfg.TransientPrompt = &TransientPrompt{}
cfg.TransientPrompt = &ExtraPrompt{}
}
return &cfg

View file

@ -266,24 +266,48 @@ func (e *Engine) RenderTooltip(tip string) string {
return ""
}
func (e *Engine) RenderTransientPrompt() string {
if e.Config.TransientPrompt == nil {
type ExtraPromptType int
const (
Transient ExtraPromptType = iota
Valid
Error
)
func (e *Engine) RenderExtraPrompt(promptType ExtraPromptType) string {
var prompt *ExtraPrompt
switch promptType {
case Transient:
prompt = e.Config.TransientPrompt
case Valid:
prompt = e.Config.ValidLine
case Error:
prompt = e.Config.ErrorLine
}
if prompt == nil {
return ""
}
promptTemplate := e.Config.TransientPrompt.Template
if len(promptTemplate) == 0 {
promptTemplate = "{{ .Shell }}> "
getTemplate := func(template string) string {
if len(template) != 0 {
return template
}
switch promptType { // nolint: exhaustive
case Transient:
return "{{ .Shell }}> "
default:
return ""
}
}
tmpl := &template.Text{
Template: promptTemplate,
Template: getTemplate(prompt.Template),
Env: e.Env,
}
prompt, err := tmpl.Render()
promptText, err := tmpl.Render()
if err != nil {
prompt = err.Error()
promptText = err.Error()
}
e.Writer.SetColors(e.Config.TransientPrompt.Background, e.Config.TransientPrompt.Foreground)
e.Writer.Write(e.Config.TransientPrompt.Background, e.Config.TransientPrompt.Foreground, prompt)
e.Writer.SetColors(prompt.Background, prompt.Foreground)
e.Writer.Write(prompt.Background, prompt.Foreground, promptText)
switch e.Env.Shell() {
case zsh:
// escape double quotes contained in the prompt

View file

@ -3,7 +3,7 @@
if ($ExecutionContext.SessionState.LanguageMode -ne "ConstrainedLanguage") {
[console]::InputEncoding = [console]::OutputEncoding = New-Object System.Text.UTF8Encoding
}
elseif ($env:POSH_CONSTRAINED_LANGUAGE_MODE -ne $true){
elseif ($env:POSH_CONSTRAINED_LANGUAGE_MODE -ne $true) {
Write-Host "[WARNING] ConstrainedLanguage mode detected, unable to set console to UTF-8.
When using PowerShell in ConstrainedLanguage mode, please set the
console mode manually to UTF-8. See here for more information:
@ -210,6 +210,13 @@ function global:Enable-PoshTransientPrompt {
}
}
function global:Enable-PoshLineError {
$omp = "::OMP::"
$validLine = @(&$omp --config="$Env:POSH_THEME" --print-valid 2>&1) -join "`n"
$errorLine = @(&$omp --config="$Env:POSH_THEME" --print-error 2>&1) -join "`n"
Set-PSReadLineOption -PromptText $validLine, $errorLine
}
<#
.SYNOPSIS
Returns an ansi formatted hyperlink

View file

@ -29,10 +29,14 @@ const (
type Args struct {
ErrorCode *int
PrintInit *bool
PrintConfig *bool
ConfigFormat *string
PrintShell *bool
PrintTransient *bool
PrintValid *bool
PrintError *bool
Config *string
ConfigFormat *string
Shell *string
PWD *string
PSWD *string
@ -42,7 +46,6 @@ type Args struct {
Millis *bool
Eval *bool
Init *bool
PrintInit *bool
ExportPNG *bool
Author *string
CursorPadding *int
@ -51,7 +54,6 @@ type Args struct {
BGColor *string
StackCount *int
Command *string
PrintTransient *bool
Plain *bool
CachePath *bool
Migrate *bool

View file

@ -133,6 +133,14 @@ func main() {
"terminal-width",
0,
"The width of the terminal"),
PrintValid: flag.Bool(
"print-valid",
false,
"Print the valid prompt"),
PrintError: flag.Bool(
"print-error",
false,
"Print the failed prompt"),
}
flag.Parse()
if *args.Version {
@ -210,7 +218,15 @@ func main() {
return
}
if *args.PrintTransient {
fmt.Print(eng.RenderTransientPrompt())
fmt.Print(eng.RenderExtraPrompt(engine.Transient))
return
}
if *args.PrintValid {
fmt.Print(eng.RenderExtraPrompt(engine.Valid))
return
}
if *args.PrintError {
fmt.Print(eng.RenderExtraPrompt(engine.Error))
return
}
if len(*args.Command) != 0 {

View file

@ -64,6 +64,18 @@
"description": "https://ohmyposh.dev/docs/config-templates",
"default": ""
},
"extra_prompt": {
"type": "object",
"default": {},
"properties": {
"template": {
"type": "string",
"title": "Prompt Template"
},
"background": { "$ref": "#/definitions/color" },
"foreground": { "$ref": "#/definitions/color" }
}
},
"block": {
"type": "object",
"description": "https://ohmyposh.dev/docs/config-overview#block",
@ -2008,7 +2020,7 @@
"tooltips": {
"type": "array",
"title": "Tooltip list, prompt elements to display based on context",
"description": "https://ohmyposh.dev/docs/beta#tooltips",
"description": "https://ohmyposh.dev/docs/config-tooltips",
"default": [],
"items": {
"allOf": [{ "$ref": "#/definitions/segment" }],
@ -2025,19 +2037,19 @@
}
},
"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 }}</>"
},
"background": { "$ref": "#/definitions/color" },
"foreground": { "$ref": "#/definitions/color" }
}
"$ref": "#/definitions/extra_prompt",
"title": "Transient Prompt Setting",
"description": "https://ohmyposh.dev/docs/config-transient"
},
"valid_line": {
"$ref": "#/definitions/extra_prompt",
"title": "Valid Prompt Setting",
"description": "https://ohmyposh.dev/docs/config-prompt-override"
},
"error_line": {
"$ref": "#/definitions/extra_prompt",
"title": "Error Prompt Setting",
"description": "https://ohmyposh.dev/docs/config-prompt-override"
},
"palette": {
"type": "object",