Skip to content

Commit

Permalink
fix(transient): handle multiline prompts better in powershell
Browse files Browse the repository at this point in the history
  • Loading branch information
JanDeDobbeleer committed Jul 10, 2021
1 parent 46b8cea commit 9576e82
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 47 deletions.
5 changes: 2 additions & 3 deletions docs/docs/beta.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ You need to extend or create a custom theme with your transient prompt. For exam
"transient_prompt": {
"background": "transparent",
"foreground": "#ffffff",
"template": "{{ .Shell }}> <#f7dc66>{{ .Command }}</>"
"template": "{{ .Shell }}> "
}
}
```
Expand All @@ -122,11 +122,10 @@ 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 }}</>`
properties below. Defaults to `{{ .Shell }}> `

#### Template Properties

- `.Command`: `string` - the shell command you typed (only available in Powershell)
- `.Root`: `boolean` - is the current user root/admin or not
- `.Path`: `string` - the current working directory
- `.Folder`: `string` - the current working folder
Expand Down
8 changes: 0 additions & 8 deletions src/ansi.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,6 @@ 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.left, strippedLen)
Expand All @@ -189,10 +185,6 @@ func (a *ansiUtils) clearAfter() string {
return a.clearLine + a.clearBelow
}

func (a *ansiUtils) newLine() string {
return a.clearAfter() + a.changeLine(1) + a.carriageBackward()
}

func (a *ansiUtils) escapeText(text string) string {
// what to escape/replace is different per shell
// maybe we should refactor and maintain a list of characters to escap/replace
Expand Down
23 changes: 4 additions & 19 deletions src/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,20 +218,16 @@ func (e *engine) renderTooltip(tip string) string {
return ""
}

func (e *engine) renderTransientPrompt(command string) string {
newlines := strings.Count(command, "\n")
command = strings.Replace(command, "\n", e.ansi.newLine(), newlines)
func (e *engine) renderTransientPrompt() string {
promptTemplate := e.config.TransientPrompt.Template
if len(promptTemplate) == 0 {
promptTemplate = "{{ .Shell }}> <#f7dc66>{{ .Command }}</>"
promptTemplate = "{{ .Shell }}> "
}
template := &textTemplate{
Template: promptTemplate,
Env: e.env,
}
context := make(map[string]interface{})
context["Command"] = command
prompt := template.renderPlainContextTemplate(context)
prompt := template.renderPlainContextTemplate(nil)
e.colorWriter.write(e.config.TransientPrompt.Background, e.config.TransientPrompt.Foreground, prompt)
switch e.env.getShellName() {
case zsh:
Expand All @@ -240,18 +236,7 @@ func (e *engine) renderTransientPrompt(command string) string {
prompt += "\nRPROMPT=\"\""
return prompt
case pwsh, powershell5:
prompt := e.ansi.carriageBackward()
// calculate offset for multiline prompt
lineOffset := 0
for _, block := range e.config.Blocks {
if block.Newline {
lineOffset--
}
}
if lineOffset != 0 {
prompt += e.ansi.changeLine(lineOffset)
}
return prompt + e.colorWriter.string() + e.ansi.clearAfter()
return e.colorWriter.string()
}
return ""
}
33 changes: 17 additions & 16 deletions src/init/omp.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ Set-DefaultEnvValue("AZ_ENABLED")
Set-DefaultEnvValue("POSH_GIT_ENABLED")

$global:PoshSettings = New-Object -TypeName PSObject -Property @{
Theme = "";
Theme = "";
Transient = $false;
}

# used to detect empty hit
Expand Down Expand Up @@ -66,6 +67,14 @@ function global:Initialize-ModuleSupport {
}

[ScriptBlock]$Prompt = {
$omp = "::OMP::"
$config, $cleanPWD, $cleanPSWD = Get-PoshContext
if ($global:PoshSettings.Transient -eq $true) {
$standardOut = @(&$omp --pwd="$cleanPWD" --pswd="$cleanPSWD" --config="$config" --print-transient 2>&1)
$standardOut -join "`n"
$global:PoshSettings.Transient = $false
return
}
#store if the last command was successful
$lastCommandSuccess = $?
#store the last exit code for restore
Expand Down Expand Up @@ -98,9 +107,12 @@ function global:Initialize-ModuleSupport {
$executionTime = ($history.EndExecutionTime - $history.StartExecutionTime).TotalMilliseconds
$global:omp_lastHistoryId = $history.Id
}
$omp = "::OMP::"
$config, $cleanPWD, $cleanPSWD = Get-PoshContext
$standardOut = @(&$omp --error="$errorCode" --pwd="$cleanPWD" --pswd="$cleanPSWD" --execution-time="$executionTime" --stack-count="$stackCount" --config="$config" 2>&1)
# make sure PSReadLine knows we have a multiline prompt
$extraLines = $standardOut.Count - 1
if ($extraLines -gt 0) {
Set-PSReadlineOption -ExtraPromptLineCount $extraLines
}
# the output can be multiline, joining these ensures proper rendering by adding line breaks with `n
$standardOut -join "`n"
$global:LASTEXITCODE = $realLASTEXITCODE
Expand Down Expand Up @@ -203,19 +215,8 @@ function global:Enable-PoshTooltips {

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)
# call twice due multiple lines:
# If the input has multiple lines, move to the start of the current line,
# or if already at the start of the line, move to the start of the input.
# If the input has a single line, move to the start of the input.
[Microsoft.PowerShell.PSConsoleReadLine]::BeginningOfLine()
[Microsoft.PowerShell.PSConsoleReadLine]::BeginningOfLine()
Write-Host $standardOut -NoNewline
$global:PoshSettings.Transient = $true
[Microsoft.PowerShell.PSConsoleReadLine]::InvokePrompt()
[Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine()
}
}
2 changes: 1 addition & 1 deletion src/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ func main() {
return
}
if *args.PrintTransient {
fmt.Print(engine.renderTransientPrompt(*args.Command))
fmt.Print(engine.renderTransientPrompt())
return
}
if len(*args.Command) != 0 {
Expand Down

0 comments on commit 9576e82

Please sign in to comment.