mirror of
https://github.com/JanDeDobbeleer/oh-my-posh.git
synced 2024-11-09 20:44:03 -08:00
fix(shell): avoid unnecessary CLI calls for prompt repaint
This commit is contained in:
parent
dbc5da5800
commit
66f1347357
|
@ -172,11 +172,11 @@ func (e *Engine) renderBlock(block *config.Block, cancelNewline bool) bool {
|
|||
defer e.patchPowerShellBleed()
|
||||
|
||||
// This is deprecated but we leave it in to not break configs
|
||||
// It is encouraged to used "newline": true on block level
|
||||
// rather than the standalone the linebreak block
|
||||
// It is encouraged to use "newline": true on block level
|
||||
// rather than the standalone linebreak block
|
||||
if block.Type == config.LineBreak {
|
||||
// do not print a newline to avoid a leading space
|
||||
// when we're printin the first primary prompt in
|
||||
// when we're printing the first primary prompt in
|
||||
// the shell
|
||||
if !cancelNewline {
|
||||
e.writeNewline()
|
||||
|
@ -191,7 +191,7 @@ func (e *Engine) renderBlock(block *config.Block, cancelNewline bool) bool {
|
|||
}
|
||||
|
||||
// do not print a newline to avoid a leading space
|
||||
// when we're printin the first primary prompt in
|
||||
// when we're printing the first primary prompt in
|
||||
// the shell
|
||||
if block.Newline && !cancelNewline {
|
||||
e.writeNewline()
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package prompt
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/jandedobbeleer/oh-my-posh/src/config"
|
||||
|
@ -9,6 +10,18 @@ import (
|
|||
)
|
||||
|
||||
func (e *Engine) Tooltip(tip string) string {
|
||||
supportedShells := []string{
|
||||
shell.ZSH,
|
||||
shell.CMD,
|
||||
shell.FISH,
|
||||
shell.PWSH,
|
||||
shell.PWSH5,
|
||||
shell.GENERIC,
|
||||
}
|
||||
if !slices.Contains(supportedShells, e.Env.Shell()) {
|
||||
return ""
|
||||
}
|
||||
|
||||
tip = strings.Trim(tip, " ")
|
||||
tooltips := make([]*config.Segment, 0, 1)
|
||||
|
||||
|
@ -35,40 +48,29 @@ func (e *Engine) Tooltip(tip string) string {
|
|||
Alignment: config.Right,
|
||||
Segments: tooltips,
|
||||
}
|
||||
block.Init(e.Env)
|
||||
if !block.Enabled() {
|
||||
return ""
|
||||
}
|
||||
text, length := e.renderBlockSegments(block)
|
||||
|
||||
switch e.Env.Shell() {
|
||||
case shell.ZSH, shell.CMD, shell.FISH, shell.GENERIC:
|
||||
block.Init(e.Env)
|
||||
if !block.Enabled() {
|
||||
return ""
|
||||
}
|
||||
text, _ := e.renderBlockSegments(block)
|
||||
return text
|
||||
case shell.PWSH, shell.PWSH5:
|
||||
if !block.Enabled() {
|
||||
e.rprompt = text
|
||||
e.rpromptLength = length
|
||||
e.currentLineLength = e.Env.Flags().Column
|
||||
space, ok := e.canWriteRightBlock(true)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
|
||||
consoleWidth, err := e.Env.TerminalWidth()
|
||||
if err != nil || consoleWidth == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
text, length := e.renderBlockSegments(block)
|
||||
|
||||
space := consoleWidth - e.Env.Flags().Column - length
|
||||
if space <= 0 {
|
||||
return ""
|
||||
}
|
||||
// clear from cursor to the end of the line in case a previous tooltip
|
||||
// is cut off and partially preserved, if the new one is shorter
|
||||
e.write(terminal.ClearAfter())
|
||||
e.write(terminal.SaveCursorPosition())
|
||||
e.write(strings.Repeat(" ", space))
|
||||
e.write(text)
|
||||
e.write(terminal.RestoreCursorPosition())
|
||||
return e.string()
|
||||
default:
|
||||
return text
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func (e *Engine) shouldInvokeWithTip(segment *config.Segment, tip string) bool {
|
||||
|
|
|
@ -1,17 +1,22 @@
|
|||
set --export POSH_THEME ::CONFIG::
|
||||
set --export POSH_SHELL_VERSION $FISH_VERSION
|
||||
set --global POWERLINE_COMMAND "oh-my-posh"
|
||||
set --global POWERLINE_COMMAND oh-my-posh
|
||||
set --global POSH_PID $fish_pid
|
||||
set --global CONDA_PROMPT_MODIFIER false
|
||||
set --global omp_tooltip_prompt ""
|
||||
set --global has_omp_tooltip false
|
||||
set --global omp_transient 0
|
||||
set --global omp_tooltip_command ''
|
||||
set --global omp_current_rprompt ''
|
||||
set --global omp_transient false
|
||||
|
||||
# We use this to avoid unnecessary CLI calls for prompt repaint.
|
||||
set --global omp_new_prompt true
|
||||
|
||||
# template function for context loading
|
||||
function set_poshcontext
|
||||
return
|
||||
return
|
||||
end
|
||||
|
||||
# NOTE: Input function calls via `commandline --function` are put into a queue and will not be executed until an outer regular function returns. See https://fishshell.com/docs/current/cmds/commandline.html.
|
||||
|
||||
function fish_prompt
|
||||
set --local omp_status_cache_temp $status
|
||||
set --local omp_pipestatus_cache_temp $pipestatus
|
||||
|
@ -19,11 +24,14 @@ function fish_prompt
|
|||
# commandline --function repaint does not do this
|
||||
# see https://github.com/fish-shell/fish-shell/issues/8418
|
||||
printf \e\[0J
|
||||
if test "$omp_transient" = "1"
|
||||
::OMP:: print transient --config $POSH_THEME --shell fish --status $omp_status_cache --pipestatus="$omp_pipestatus_cache" --execution-time $omp_duration --stack-count $omp_stack_count --shell-version $FISH_VERSION --no-status=$omp_no_exit_code
|
||||
return
|
||||
if test "$omp_transient" = true
|
||||
::OMP:: print transient --config $POSH_THEME --shell fish --status $omp_status_cache --pipestatus="$omp_pipestatus_cache" --execution-time $omp_duration --stack-count $omp_stack_count --shell-version $FISH_VERSION --no-status=$omp_no_exit_code
|
||||
return
|
||||
end
|
||||
if test "$omp_new_prompt" = false
|
||||
echo -n "$omp_current_prompt"
|
||||
return
|
||||
end
|
||||
|
||||
set --global omp_status_cache $omp_status_cache_temp
|
||||
set --global omp_pipestatus_cache $omp_pipestatus_cache_temp
|
||||
set --global omp_stack_count (count $dirstack)
|
||||
|
@ -31,22 +39,22 @@ function fish_prompt
|
|||
set --global omp_no_exit_code false
|
||||
|
||||
# check if variable set, < 3.2 case
|
||||
if set --query omp_lastcommand; and test "$omp_lastcommand" = ""
|
||||
set omp_duration 0
|
||||
set omp_no_exit_code true
|
||||
if set --query omp_lastcommand; and test -z "$omp_lastcommand"
|
||||
set omp_duration 0
|
||||
set omp_no_exit_code true
|
||||
end
|
||||
|
||||
# works with fish >=3.2
|
||||
if set --query omp_last_status_generation; and test "$omp_last_status_generation" = "$status_generation"
|
||||
set omp_duration 0
|
||||
set omp_no_exit_code true
|
||||
set omp_duration 0
|
||||
set omp_no_exit_code true
|
||||
else if test -z "$omp_last_status_generation"
|
||||
# first execution - $status_generation is 0, $omp_last_status_generation is empty
|
||||
set omp_no_exit_code true
|
||||
# first execution - $status_generation is 0, $omp_last_status_generation is empty
|
||||
set omp_no_exit_code true
|
||||
end
|
||||
|
||||
if set --query status_generation
|
||||
set --global --export omp_last_status_generation $status_generation
|
||||
set --global omp_last_status_generation $status_generation
|
||||
end
|
||||
|
||||
set_poshcontext
|
||||
|
@ -55,112 +63,146 @@ function fish_prompt
|
|||
set --local omp_cleared false
|
||||
set --local last_command (history search --max 1)
|
||||
|
||||
if test "$last_command" = "clear"
|
||||
set omp_cleared true
|
||||
if test "$last_command" = clear
|
||||
set omp_cleared true
|
||||
end
|
||||
|
||||
::PROMPT_MARK::
|
||||
|
||||
::OMP:: print primary --config $POSH_THEME --shell fish --status $omp_status_cache --pipestatus="$omp_pipestatus_cache" --execution-time $omp_duration --stack-count $omp_stack_count --shell-version $FISH_VERSION --cleared=$omp_cleared --no-status=$omp_no_exit_code
|
||||
# The prompt is saved for possible reuse, typically a repaint after clearing the screen buffer.
|
||||
set --global omp_current_prompt (::OMP:: print primary --config $POSH_THEME --shell fish --status $omp_status_cache --pipestatus="$omp_pipestatus_cache" --execution-time $omp_duration --stack-count $omp_stack_count --shell-version $FISH_VERSION --cleared=$omp_cleared --no-status=$omp_no_exit_code | string collect)
|
||||
echo -n "$omp_current_prompt"
|
||||
end
|
||||
|
||||
function fish_right_prompt
|
||||
if test "$omp_transient" = "1"
|
||||
echo -n ""
|
||||
set omp_transient 0
|
||||
set has_omp_tooltip false
|
||||
return
|
||||
if test "$omp_transient" = true
|
||||
set omp_transient false
|
||||
return
|
||||
end
|
||||
if test -n "$omp_tooltip_prompt"
|
||||
echo -n $omp_tooltip_prompt
|
||||
set omp_tooltip_prompt ""
|
||||
set has_omp_tooltip true
|
||||
return
|
||||
# Repaint an existing right prompt.
|
||||
if test "$omp_new_prompt" = false
|
||||
echo -n "$omp_current_rprompt"
|
||||
return
|
||||
end
|
||||
set has_omp_tooltip false
|
||||
::OMP:: print right --config $POSH_THEME --shell fish --status $omp_status_cache --execution-time $omp_duration --stack-count $omp_stack_count --shell-version $FISH_VERSION
|
||||
set omp_new_prompt false
|
||||
set --global omp_current_rprompt (::OMP:: print right --config $POSH_THEME --shell fish --status $omp_status_cache --pipestatus="$omp_pipestatus_cache" --execution-time $omp_duration --stack-count $omp_stack_count --shell-version $FISH_VERSION --no-status=$omp_no_exit_code | string join '')
|
||||
echo -n "$omp_current_rprompt"
|
||||
end
|
||||
|
||||
function postexec_omp --on-event fish_postexec
|
||||
# works with fish <3.2
|
||||
# pre and postexec not fired for empty command in fish >=3.2
|
||||
set --global --export omp_lastcommand $argv
|
||||
end
|
||||
|
||||
# fix tooltip not resetting on SIGINT (ctrl+c)
|
||||
function sigint_omp --on-signal INT
|
||||
commandline --function repaint
|
||||
# works with fish <3.2
|
||||
# pre and postexec not fired for empty command in fish >=3.2
|
||||
set --global omp_lastcommand $argv
|
||||
end
|
||||
|
||||
function preexec_omp --on-event fish_preexec
|
||||
if "::FTCS_MARKS::" = "true"
|
||||
echo -ne "\e]133;C\a"
|
||||
end
|
||||
if test "::FTCS_MARKS::" = true
|
||||
echo -ne "\e]133;C\a"
|
||||
end
|
||||
end
|
||||
|
||||
# perform cleanup so a new initialization in current session works
|
||||
if test "$(string match -e '_render_transient' $(bind \r --user 2>/dev/null))" != ''
|
||||
bind -e \r
|
||||
if test -n (bind \r --user 2>/dev/null | string match -e _omp_enter_key_handler)
|
||||
bind -e \r -M default
|
||||
bind -e \r -M insert
|
||||
bind -e \r -M visual
|
||||
end
|
||||
if test "$(string match -e '_render_tooltip' $(bind \x20 --user 2>/dev/null))" != ''
|
||||
bind -e \x20
|
||||
if test -n (bind \n --user 2>/dev/null | string match -e _omp_enter_key_handler)
|
||||
bind -e \n -M default
|
||||
bind -e \n -M insert
|
||||
bind -e \n -M visual
|
||||
end
|
||||
if test -n (bind \cc --user 2>/dev/null | string match -e _omp_ctrl_c_key_handler)
|
||||
bind -e \cc -M default
|
||||
bind -e \cc -M insert
|
||||
bind -e \cc -M visual
|
||||
end
|
||||
if test -n (bind \x20 --user 2>/dev/null | string match -e _omp_space_key_handler)
|
||||
bind -e \x20 -M default
|
||||
bind -e \x20 -M insert
|
||||
end
|
||||
|
||||
# tooltip
|
||||
|
||||
function _render_tooltip
|
||||
commandline --function expand-abbr
|
||||
commandline --insert " "
|
||||
# get the first word of command line as tip
|
||||
set omp_tooltip_command (commandline --current-buffer | string trim -l | string split --allow-empty -f1 ' ' | string collect)
|
||||
if not test -n "$omp_tooltip_command"
|
||||
return
|
||||
end
|
||||
set omp_tooltip_prompt (::OMP:: print tooltip --config $POSH_THEME --shell fish --status $omp_status_cache --shell-version $FISH_VERSION --command $omp_tooltip_command)
|
||||
if not test -n "$omp_tooltip_prompt"
|
||||
if test "$has_omp_tooltip" = "true"
|
||||
commandline --function repaint
|
||||
function _omp_space_key_handler
|
||||
commandline --function expand-abbr
|
||||
commandline --insert ' '
|
||||
# Get the first word of command line as tip.
|
||||
set --local tooltip_command (commandline --current-buffer | string trim -l | string split --allow-empty -f1 ' ' | string collect)
|
||||
# Ignore an empty/repeated tooltip command.
|
||||
if test -z "$tooltip_command" || test "$tooltip_command" = "$omp_tooltip_command"
|
||||
return
|
||||
end
|
||||
return
|
||||
end
|
||||
commandline --function repaint
|
||||
set omp_tooltip_command $tooltip_command
|
||||
set --local tooltip_prompt (::OMP:: print tooltip --config $POSH_THEME --shell fish --status $omp_status_cache --pipestatus="$omp_pipestatus_cache" --execution-time $omp_duration --stack-count $omp_stack_count --shell-version $FISH_VERSION --command $omp_tooltip_command --no-status=$omp_no_exit_code | string join '')
|
||||
if test -z "$tooltip_prompt"
|
||||
return
|
||||
end
|
||||
# Save the tooltip prompt to avoid unnecessary CLI calls.
|
||||
set omp_current_rprompt $tooltip_prompt
|
||||
commandline --function repaint
|
||||
end
|
||||
|
||||
if test "::TOOLTIPS::" = "true"
|
||||
bind \x20 _render_tooltip -M default
|
||||
bind \x20 _render_tooltip -M insert
|
||||
if test "::TOOLTIPS::" = true
|
||||
bind \x20 _omp_space_key_handler -M default
|
||||
bind \x20 _omp_space_key_handler -M insert
|
||||
end
|
||||
|
||||
# transient prompt
|
||||
|
||||
function _render_transient
|
||||
if commandline --paging-mode
|
||||
commandline --function accept-autosuggestion
|
||||
return
|
||||
end
|
||||
set omp_transient 1
|
||||
commandline --function repaint
|
||||
commandline --function execute
|
||||
function _omp_enter_key_handler
|
||||
if commandline --paging-mode
|
||||
commandline --function accept-autosuggestion
|
||||
return
|
||||
end
|
||||
if commandline --is-valid || test -z (commandline --current-buffer | string trim -l | string collect)
|
||||
set omp_new_prompt true
|
||||
set omp_tooltip_command ''
|
||||
if test "::TRANSIENT::" = true
|
||||
set omp_transient true
|
||||
commandline --function repaint
|
||||
end
|
||||
end
|
||||
commandline --function execute
|
||||
end
|
||||
|
||||
if test "::TRANSIENT::" = "true"
|
||||
bind \r _render_transient -M default
|
||||
bind \r _render_transient -M insert
|
||||
bind \r _render_transient -M visual
|
||||
function _omp_ctrl_c_key_handler
|
||||
if test -z (commandline --current-buffer | string collect)
|
||||
return
|
||||
end
|
||||
# Render a transient prompt on Ctrl-C with non-empty command line buffer.
|
||||
set omp_new_prompt true
|
||||
set omp_tooltip_command ''
|
||||
if test "::TRANSIENT::" = true
|
||||
set omp_transient true
|
||||
commandline --function repaint
|
||||
end
|
||||
commandline --function cancel-commandline
|
||||
commandline --function repaint
|
||||
end
|
||||
|
||||
bind \r _omp_enter_key_handler -M default
|
||||
bind \r _omp_enter_key_handler -M insert
|
||||
bind \r _omp_enter_key_handler -M visual
|
||||
bind \n _omp_enter_key_handler -M default
|
||||
bind \n _omp_enter_key_handler -M insert
|
||||
bind \n _omp_enter_key_handler -M visual
|
||||
bind \cc _omp_ctrl_c_key_handler -M default
|
||||
bind \cc _omp_ctrl_c_key_handler -M insert
|
||||
bind \cc _omp_ctrl_c_key_handler -M visual
|
||||
|
||||
# legacy functions
|
||||
function enable_poshtooltips
|
||||
return
|
||||
return
|
||||
end
|
||||
function enable_poshtransientprompt
|
||||
return
|
||||
return
|
||||
end
|
||||
|
||||
if test "::UPGRADE::" = "true"
|
||||
echo "::UPGRADENOTICE::"
|
||||
if test "::UPGRADE::" = true
|
||||
echo "::UPGRADENOTICE::"
|
||||
end
|
||||
|
||||
if test "::AUTOUPGRADE::" = "true"
|
||||
::OMP:: upgrade
|
||||
if test "::AUTOUPGRADE::" = true
|
||||
::OMP:: upgrade
|
||||
end
|
||||
|
|
|
@ -14,20 +14,29 @@ function global:Get-PoshStackCount {
|
|||
}
|
||||
|
||||
New-Module -Name "oh-my-posh-core" -ScriptBlock {
|
||||
# Check `ConstrainedLanguage` mode.
|
||||
$script:ConstrainedLanguageMode = $ExecutionContext.SessionState.LanguageMode -eq "ConstrainedLanguage"
|
||||
|
||||
# Prompt related backup.
|
||||
$script:OriginalPromptFunction = $Function:prompt
|
||||
$script:OriginalContinuationPrompt = (Get-PSReadLineOption).ContinuationPrompt
|
||||
$script:OriginalPromptText = (Get-PSReadLineOption).PromptText
|
||||
|
||||
$script:NoExitCode = $true
|
||||
$script:ErrorCode = 0
|
||||
$script:ExecutionTime = 0
|
||||
$script:OMPExecutable = ::OMP::
|
||||
$script:ShellName = "::SHELL::"
|
||||
$script:PSVersion = $PSVersionTable.PSVersion.ToString()
|
||||
$script:TransientPrompt = $false
|
||||
$script:ToolTipCommand = ""
|
||||
$script:TooltipCommand = ''
|
||||
$env:POWERLINE_COMMAND = "oh-my-posh"
|
||||
$env:POSH_SHELL_VERSION = $script:PSVersion
|
||||
$env:POSH_PID = $PID
|
||||
$env:CONDA_PROMPT_MODIFIER = $false
|
||||
|
||||
# set the default theme
|
||||
if ((::CONFIG:: -ne '') -and (Test-Path -LiteralPath ::CONFIG::)) {
|
||||
if (::CONFIG:: -and (Test-Path -LiteralPath ::CONFIG::)) {
|
||||
$env:POSH_THEME = (Resolve-Path -Path ::CONFIG::).ProviderPath
|
||||
}
|
||||
|
||||
|
@ -56,7 +65,7 @@ New-Module -Name "oh-my-posh-core" -ScriptBlock {
|
|||
[string[]]$Arguments = @()
|
||||
)
|
||||
|
||||
if ($ExecutionContext.SessionState.LanguageMode -eq "ConstrainedLanguage") {
|
||||
if ($script:ConstrainedLanguageMode) {
|
||||
$standardOut = Invoke-Expression "& `$FileName `$Arguments 2>&1"
|
||||
$standardOut -join "`n"
|
||||
return
|
||||
|
@ -99,12 +108,14 @@ New-Module -Name "oh-my-posh-core" -ScriptBlock {
|
|||
}
|
||||
$StartInfo.CreateNoWindow = $true
|
||||
[void]$Process.Start()
|
||||
# we do this to remove a deadlock potential on Windows
|
||||
|
||||
# Remove deadlock potential on Windows.
|
||||
$stdoutTask = $Process.StandardOutput.ReadToEndAsync()
|
||||
$stderrTask = $Process.StandardError.ReadToEndAsync()
|
||||
|
||||
$Process.WaitForExit()
|
||||
$stderr = $stderrTask.Result.Trim()
|
||||
if ($stderr -ne '') {
|
||||
if ($stderr) {
|
||||
$Host.UI.WriteErrorLine($stderr)
|
||||
}
|
||||
$stdoutTask.Result
|
||||
|
@ -120,77 +131,79 @@ New-Module -Name "oh-my-posh-core" -ScriptBlock {
|
|||
return $pswd
|
||||
}
|
||||
|
||||
if (("::TOOLTIPS::" -eq "true") -and ($ExecutionContext.SessionState.LanguageMode -ne "ConstrainedLanguage")) {
|
||||
Set-PSReadLineKeyHandler -Key Spacebar -BriefDescription 'OhMyPoshSpaceKeyHandler' -ScriptBlock {
|
||||
[Microsoft.PowerShell.PSConsoleReadLine]::Insert(' ')
|
||||
$command = $null
|
||||
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$command, [ref]$null)
|
||||
$command = $command.TrimStart().Split(" ", 2) | Select-Object -First 1
|
||||
# ignore an empty/repeated tip
|
||||
if ($command -eq '' -or $command -eq $script:ToolTipCommand) {
|
||||
return
|
||||
}
|
||||
$position = $host.UI.RawUI.CursorPosition
|
||||
$terminalWidth = $Host.UI.RawUI.WindowSize.Width
|
||||
$cleanPSWD = Get-CleanPSWD
|
||||
$standardOut = @(Start-Utf8Process $script:OMPExecutable @("print", "tooltip", "--status=$script:ErrorCode", "--shell=$script:ShellName", "--pswd=$cleanPSWD", "--config=$env:POSH_THEME", "--command=$command", "--shell-version=$script:PSVersion", "--column=$($position.X)", "--terminal-width=$terminalWidth"))
|
||||
# ignore an empty tooltip
|
||||
if ($standardOut -eq '') {
|
||||
return
|
||||
}
|
||||
Write-Host $standardOut -NoNewline
|
||||
$host.UI.RawUI.CursorPosition = $position
|
||||
# cache the tip command
|
||||
$script:ToolTipCommand = $command
|
||||
# we need this workaround to prevent the text after cursor from disappearing when the tooltip is rendered
|
||||
[Microsoft.PowerShell.PSConsoleReadLine]::Insert(' ')
|
||||
[Microsoft.PowerShell.PSConsoleReadLine]::Undo()
|
||||
function Get-TerminalWidth {
|
||||
$terminalWidth = $Host.UI.RawUI.WindowSize.Width
|
||||
# Set a sane default when the value can't be retrieved.
|
||||
if (-not $terminalWidth) {
|
||||
return 0
|
||||
}
|
||||
$terminalWidth
|
||||
}
|
||||
|
||||
function Set-TransientPrompt {
|
||||
$previousOutputEncoding = [Console]::OutputEncoding
|
||||
$executingCommand = $false
|
||||
if (!$script:ConstrainedLanguageMode) {
|
||||
if ('::TOOLTIPS::' -eq 'true') {
|
||||
Set-PSReadLineKeyHandler -Key Spacebar -BriefDescription 'OhMyPoshSpaceKeyHandler' -ScriptBlock {
|
||||
param([ConsoleKeyInfo]$key)
|
||||
[Microsoft.PowerShell.PSConsoleReadLine]::SelfInsert($key)
|
||||
try {
|
||||
$command = ''
|
||||
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$command, [ref]$null)
|
||||
# Get the first word of command line as tip.
|
||||
$command = $command.TrimStart().Split(' ', 2) | Select-Object -First 1
|
||||
# Ignore an empty/repeated tooltip command.
|
||||
if (!$command -or ($command -eq $script:TooltipCommand)) {
|
||||
return
|
||||
}
|
||||
$script:TooltipCommand = $command
|
||||
$column = $Host.UI.RawUI.CursorPosition.X
|
||||
$terminalWidth = Get-TerminalWidth
|
||||
$cleanPSWD = Get-CleanPSWD
|
||||
$stackCount = global:Get-PoshStackCount
|
||||
$standardOut = (Start-Utf8Process $script:OMPExecutable @("print", "tooltip", "--status=$script:ErrorCode", "--shell=$script:ShellName", "--pswd=$cleanPSWD", "--execution-time=$script:ExecutionTime", "--stack-count=$stackCount", "--config=$env:POSH_THEME", "--command=$command", "--shell-version=$script:PSVersion", "--column=$column", "--terminal-width=$terminalWidth", "--no-status=$script:NoExitCode")) -join ''
|
||||
if (!$standardOut) {
|
||||
return
|
||||
}
|
||||
Write-Host $standardOut -NoNewline
|
||||
|
||||
try {
|
||||
$parseErrors = $null
|
||||
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$null, [ref]$null, [ref]$parseErrors, [ref]$null)
|
||||
if ($parseErrors.Count -eq 0) {
|
||||
$executingCommand = $true
|
||||
# Workaround to prevent the text after cursor from disappearing when the tooltip is printed.
|
||||
[Microsoft.PowerShell.PSConsoleReadLine]::Insert(' ')
|
||||
[Microsoft.PowerShell.PSConsoleReadLine]::Undo()
|
||||
}
|
||||
finally {}
|
||||
}
|
||||
}
|
||||
|
||||
function Set-TransientPrompt {
|
||||
$previousOutputEncoding = [Console]::OutputEncoding
|
||||
try {
|
||||
$script:TransientPrompt = $true
|
||||
[Console]::OutputEncoding = [Text.Encoding]::UTF8
|
||||
[Microsoft.PowerShell.PSConsoleReadLine]::InvokePrompt()
|
||||
}
|
||||
}
|
||||
finally {
|
||||
# If PSReadline is set to display suggestion list, this workaround is needed to clear the buffer below
|
||||
# before accepting the current commandline. The max amount of items in the list is 10, so 12 lines
|
||||
# are cleared (10 + 1 more for the prompt + 1 more for current commandline).
|
||||
if ((Get-PSReadLineOption).PredictionViewStyle -eq 'ListView') {
|
||||
$terminalHeight = $Host.UI.RawUI.WindowSize.Height
|
||||
# only do this on an valid value
|
||||
if ([int]$terminalHeight -gt 0) {
|
||||
[Microsoft.PowerShell.PSConsoleReadLine]::Insert("`n" * [System.Math]::Min($terminalHeight - $Host.UI.RawUI.CursorPosition.Y - 1, 12))
|
||||
[Microsoft.PowerShell.PSConsoleReadLine]::Undo()
|
||||
}
|
||||
finally {
|
||||
[Console]::OutputEncoding = $previousOutputEncoding
|
||||
}
|
||||
[Console]::OutputEncoding = $previousOutputEncoding
|
||||
}
|
||||
|
||||
return $executingCommand
|
||||
}
|
||||
|
||||
if (("::TRANSIENT::" -eq "true") -and ($ExecutionContext.SessionState.LanguageMode -ne "ConstrainedLanguage")) {
|
||||
Set-PSReadLineKeyHandler -Key Enter -BriefDescription 'OhMyPoshEnterKeyHandler' -ScriptBlock {
|
||||
try {
|
||||
$executingCommand = Set-TransientPrompt
|
||||
$parseErrors = $null
|
||||
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$null, [ref]$null, [ref]$parseErrors, [ref]$null)
|
||||
$executingCommand = $parseErrors.Count -eq 0
|
||||
if ($executingCommand) {
|
||||
$script:TooltipCommand = ''
|
||||
if ('::TRANSIENT::' -eq 'true') {
|
||||
Set-TransientPrompt
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
[Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine()
|
||||
# Write FTCS_COMMAND_EXECUTED after accepting the input - it should still happen before execution
|
||||
if (("::FTCS_MARKS::" -eq "true") -and $executingCommand) {
|
||||
if (('::FTCS_MARKS::' -eq 'true') -and $executingCommand) {
|
||||
# Write FTCS_COMMAND_EXECUTED after accepting the input - it should still happen before execution
|
||||
Write-Host "$([char]0x1b)]133;C`a" -NoNewline
|
||||
}
|
||||
}
|
||||
finally {}
|
||||
}
|
||||
Set-PSReadLineKeyHandler -Key Ctrl+c -BriefDescription 'OhMyPoshCtrlCKeyHandler' -ScriptBlock {
|
||||
try {
|
||||
|
@ -198,37 +211,21 @@ New-Module -Name "oh-my-posh-core" -ScriptBlock {
|
|||
[Microsoft.PowerShell.PSConsoleReadLine]::GetSelectionState([ref]$start, [ref]$null)
|
||||
# only render a transient prompt when no text is selected
|
||||
if ($start -eq -1) {
|
||||
Set-TransientPrompt
|
||||
$script:TooltipCommand = ''
|
||||
if ('::TRANSIENT::' -eq 'true') {
|
||||
Set-TransientPrompt
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {}
|
||||
|
||||
[Microsoft.PowerShell.PSConsoleReadLine]::CopyOrCancelLine()
|
||||
}
|
||||
}
|
||||
|
||||
if (("::FTCS_MARKS::" -eq "true") -and ("::TRANSIENT::" -ne "true") -and ($ExecutionContext.SessionState.LanguageMode -ne "ConstrainedLanguage")) {
|
||||
Set-PSReadLineKeyHandler -Key Enter -BriefDescription 'OhMyPoshEnterKeyHandler' -ScriptBlock {
|
||||
$executingCommand = $false
|
||||
try {
|
||||
$parseErrors = $null
|
||||
[Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$null, [ref]$null, [ref]$parseErrors, [ref]$null)
|
||||
$executingCommand = $parseErrors.Count -eq 0
|
||||
}
|
||||
finally {}
|
||||
|
||||
[Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine()
|
||||
|
||||
# Write FTCS_COMMAND_EXECUTED after accepting the input - it should still happen before execution
|
||||
if ($executingCommand) {
|
||||
Write-Host "$([char]0x1b)]133;C`a" -NoNewline
|
||||
finally {
|
||||
[Microsoft.PowerShell.PSConsoleReadLine]::CopyOrCancelLine()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ("::ERROR_LINE::" -eq "true") {
|
||||
$validLine = @(Start-Utf8Process $script:OMPExecutable @("print", "valid", "--config=$env:POSH_THEME", "--shell=$script:ShellName")) -join "`n"
|
||||
$errorLine = @(Start-Utf8Process $script:OMPExecutable @("print", "error", "--config=$env:POSH_THEME", "--shell=$script:ShellName")) -join "`n"
|
||||
$validLine = (Start-Utf8Process $script:OMPExecutable @("print", "valid", "--config=$env:POSH_THEME", "--shell=$script:ShellName")) -join "`n"
|
||||
$errorLine = (Start-Utf8Process $script:OMPExecutable @("print", "error", "--config=$env:POSH_THEME", "--shell=$script:ShellName")) -join "`n"
|
||||
Set-PSReadLineOption -PromptText $validLine, $errorLine
|
||||
}
|
||||
|
||||
|
@ -267,9 +264,9 @@ New-Module -Name "oh-my-posh-core" -ScriptBlock {
|
|||
$Format = 'json'
|
||||
)
|
||||
|
||||
$configString = @(Start-Utf8Process $script:OMPExecutable @("config", "export", "--config=$env:POSH_THEME", "--format=$Format"))
|
||||
$configString = Start-Utf8Process $script:OMPExecutable @("config", "export", "--config=$env:POSH_THEME", "--format=$Format")
|
||||
# if no path, copy to clipboard by default
|
||||
if ('' -ne $FilePath) {
|
||||
if ($FilePath) {
|
||||
# https://stackoverflow.com/questions/3038337/powershell-resolve-path-that-might-not-exist
|
||||
$FilePath = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($FilePath)
|
||||
[IO.File]::WriteAllLines($FilePath, $configString)
|
||||
|
@ -288,7 +285,7 @@ New-Module -Name "oh-my-posh-core" -ScriptBlock {
|
|||
[string]$name
|
||||
)
|
||||
$esc = [char]27
|
||||
if ("" -eq $name) {
|
||||
if (!$name) {
|
||||
# if name not set, uri is used as the name of the hyperlink
|
||||
$name = $uri
|
||||
}
|
||||
|
@ -335,7 +332,7 @@ New-Module -Name "oh-my-posh-core" -ScriptBlock {
|
|||
$cleanPSWD = Get-CleanPSWD
|
||||
$themes | ForEach-Object -Process {
|
||||
Write-Host "Theme: $(Get-FileHyperlink -uri $_.FullName -Name ($_.BaseName -replace '\.omp$', ''))`n"
|
||||
@(Start-Utf8Process $script:OMPExecutable @("print", "primary", "--config=$($_.FullName)", "--pswd=$cleanPSWD", "--shell=$script:ShellName"))
|
||||
Start-Utf8Process $script:OMPExecutable @("print", "primary", "--config=$($_.FullName)", "--pswd=$cleanPSWD", "--shell=$script:ShellName")
|
||||
Write-Host "`n"
|
||||
}
|
||||
}
|
||||
|
@ -400,7 +397,7 @@ Example:
|
|||
}
|
||||
}
|
||||
|
||||
function prompt {
|
||||
$promptFunction = {
|
||||
# store the orignal last command execution status
|
||||
if ($global:NVS_ORIGINAL_LASTEXECUTIONSTATUS -is [bool]) {
|
||||
# make it compatible with NVS auto-switching, if enabled
|
||||
|
@ -419,41 +416,30 @@ Example:
|
|||
$cleanPSWD = Get-CleanPSWD
|
||||
$stackCount = global:Get-PoshStackCount
|
||||
Set-PoshContext
|
||||
$terminalWidth = $Host.UI.RawUI.WindowSize.Width
|
||||
# set a sane default when the value can't be retrieved
|
||||
if (-not $terminalWidth) {
|
||||
$terminalWidth = 0
|
||||
}
|
||||
|
||||
# in some cases we have an empty $script:NoExitCode
|
||||
# this is a workaround to make sure we always have a value
|
||||
# see https://github.com/JanDeDobbeleer/oh-my-posh/issues/4128
|
||||
if ($null -eq $script:NoExitCode) {
|
||||
$script:NoExitCode = $true
|
||||
}
|
||||
$terminalWidth = Get-TerminalWidth
|
||||
|
||||
# set the cursor positions, they are zero based so align with other platforms
|
||||
$env:POSH_CURSOR_LINE = $Host.UI.RawUI.CursorPosition.Y + 1
|
||||
$env:POSH_CURSOR_COLUMN = $Host.UI.RawUI.CursorPosition.X + 1
|
||||
|
||||
$standardOut = @(Start-Utf8Process $script:OMPExecutable @("print", $script:PromptType, "--status=$script:ErrorCode", "--pswd=$cleanPSWD", "--execution-time=$script:ExecutionTime", "--stack-count=$stackCount", "--config=$env:POSH_THEME", "--shell-version=$script:PSVersion", "--terminal-width=$terminalWidth", "--shell=$script:ShellName", "--no-status=$script:NoExitCode"))
|
||||
$standardOut = Start-Utf8Process $script:OMPExecutable @("print", $script:PromptType, "--status=$script:ErrorCode", "--pswd=$cleanPSWD", "--execution-time=$script:ExecutionTime", "--stack-count=$stackCount", "--config=$env:POSH_THEME", "--shell-version=$script:PSVersion", "--terminal-width=$terminalWidth", "--shell=$script:ShellName", "--no-status=$script:NoExitCode")
|
||||
# make sure PSReadLine knows if we have a multiline prompt
|
||||
Set-PSReadLineOption -ExtraPromptLineCount (($standardOut | Measure-Object -Line).Lines - 1)
|
||||
# the output can be multiline, joining these ensures proper rendering by adding line breaks with `n
|
||||
|
||||
# The output can be multi-line, joining them ensures proper rendering.
|
||||
$standardOut -join "`n"
|
||||
|
||||
# remove any posh-git status
|
||||
$env:POSH_GIT_STATUS = $null
|
||||
|
||||
# remove cached tip command
|
||||
$script:ToolTipCommand = ""
|
||||
|
||||
# restore the orignal last exit code
|
||||
$global:LASTEXITCODE = $script:OriginalLastExitCode
|
||||
}
|
||||
|
||||
$Function:prompt = $promptFunction
|
||||
|
||||
# set secondary prompt
|
||||
Set-PSReadLineOption -ContinuationPrompt (@(Start-Utf8Process $script:OMPExecutable @("print", "secondary", "--config=$env:POSH_THEME", "--shell=$script:ShellName")) -join "`n")
|
||||
Set-PSReadLineOption -ContinuationPrompt ((Start-Utf8Process $script:OMPExecutable @("print", "secondary", "--config=$env:POSH_THEME", "--shell=$script:ShellName")) -join "`n")
|
||||
|
||||
# legacy functions
|
||||
function Enable-PoshTooltips {}
|
||||
|
@ -461,21 +447,25 @@ Example:
|
|||
function Enable-PoshLineError {}
|
||||
|
||||
# perform cleanup on removal so a new initialization in current session works
|
||||
if ($ExecutionContext.SessionState.LanguageMode -ne "ConstrainedLanguage") {
|
||||
if (!$script:ConstrainedLanguageMode) {
|
||||
$ExecutionContext.SessionState.Module.OnRemove += {
|
||||
if ((Get-PSReadLineKeyHandler -Key Spacebar).Function -eq 'OhMyPoshSpaceKeyHandler') {
|
||||
Remove-PSReadLineKeyHandler -Key Spacebar
|
||||
Remove-Item Function:Get-PoshStackCount
|
||||
$Function:prompt = $script:OriginalPromptFunction
|
||||
(Get-PSReadLineOption).ContinuationPrompt = $script:OriginalContinuationPrompt
|
||||
(Get-PSReadLineOption).PromptText = $script:OriginalPromptText
|
||||
if ((Get-PSReadLineKeyHandler Spacebar).Function -eq 'OhMyPoshSpaceKeyHandler') {
|
||||
Remove-PSReadLineKeyHandler Spacebar
|
||||
}
|
||||
if ((Get-PSReadLineKeyHandler -Key Enter).Function -eq 'OhMyPoshEnterKeyHandler') {
|
||||
Set-PSReadLineKeyHandler -Key Enter -Function AcceptLine
|
||||
if ((Get-PSReadLineKeyHandler Enter).Function -eq 'OhMyPoshEnterKeyHandler') {
|
||||
Set-PSReadLineKeyHandler Enter -Function AcceptLine
|
||||
}
|
||||
if ((Get-PSReadLineKeyHandler -Key Ctrl+c).Function -eq 'OhMyPoshCtrlCKeyHandler') {
|
||||
Set-PSReadLineKeyHandler -Key Ctrl+c -Function CopyOrCancelLine
|
||||
if ((Get-PSReadLineKeyHandler Ctrl+c).Function -eq 'OhMyPoshCtrlCKeyHandler') {
|
||||
Set-PSReadLineKeyHandler Ctrl+c -Function CopyOrCancelLine
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$notice = @(Start-Utf8Process $script:OMPExecutable @("notice"))
|
||||
$notice = Start-Utf8Process $script:OMPExecutable @("notice")
|
||||
if ($notice) {
|
||||
Write-Host $notice -NoNewline
|
||||
}
|
||||
|
@ -488,7 +478,6 @@ Example:
|
|||
"Export-PoshTheme"
|
||||
"Get-PoshThemes"
|
||||
"Start-Utf8Process"
|
||||
"prompt"
|
||||
)
|
||||
} | Import-Module -Global
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ function _set_posh_cursor_position() {
|
|||
stty raw -echo min 0
|
||||
|
||||
local pos
|
||||
echo -en "\033[6n" > /dev/tty
|
||||
echo -en "\033[6n" >/dev/tty
|
||||
read -r -d R pos
|
||||
pos=${pos:2} # strip off the esc-[
|
||||
local parts=(${(s:;:)pos})
|
||||
|
@ -44,24 +44,24 @@ function prompt_ohmyposh_preexec() {
|
|||
}
|
||||
|
||||
function prompt_ohmyposh_precmd() {
|
||||
omp_last_error=$?
|
||||
local pipeStatus=(${pipestatus[@]})
|
||||
omp_status_cache=$?
|
||||
omp_pipestatus_cache=(${pipestatus[@]})
|
||||
omp_stack_count=${#dirstack[@]}
|
||||
omp_elapsed=-1
|
||||
no_exit_code="true"
|
||||
omp_no_exit_code="true"
|
||||
if [ $omp_start_time ]; then
|
||||
local omp_now=$(::OMP:: get millis --shell=zsh)
|
||||
omp_elapsed=$(($omp_now-$omp_start_time))
|
||||
no_exit_code="false"
|
||||
omp_elapsed=$(($omp_now - $omp_start_time))
|
||||
omp_no_exit_code="false"
|
||||
fi
|
||||
if [[ "${pipeStatus[-1]}" != "$omp_last_error" ]]; then
|
||||
pipeStatus=("$omp_last_error")
|
||||
if [[ "${omp_pipestatus_cache[-1]}" != "$omp_status_cache" ]]; then
|
||||
omp_pipestatus_cache=("$omp_status_cache")
|
||||
fi
|
||||
count=$((POSH_PROMPT_COUNT+1))
|
||||
count=$((POSH_PROMPT_COUNT + 1))
|
||||
export POSH_PROMPT_COUNT=$count
|
||||
set_poshcontext
|
||||
_set_posh_cursor_position
|
||||
eval "$(::OMP:: print primary --config="$POSH_THEME" --status="$omp_last_error" --pipestatus="${pipeStatus[*]}" --execution-time="$omp_elapsed" --stack-count="$omp_stack_count" --eval --shell=zsh --shell-version="$ZSH_VERSION" --no-status="$no_exit_code")"
|
||||
eval "$(::OMP:: print primary --config="$POSH_THEME" --status="$omp_status_cache" --pipestatus="${omp_pipestatus_cache[*]}" --execution-time="$omp_elapsed" --stack-count="$omp_stack_count" --eval --shell=zsh --shell-version="$ZSH_VERSION" --no-status="$omp_no_exit_code")"
|
||||
unset omp_start_time
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,7 @@ function _posh-tooltip() {
|
|||
# https://github.com/zsh-users/zsh-autosuggestions - clear suggestion to avoid keeping it after the newly inserted space
|
||||
if [[ "$(zle -lL autosuggest-clear)" ]]; then
|
||||
# only if suggestions not disabled (variable not set)
|
||||
if ! [[ -v _ZSH_AUTOSUGGEST_DISABLED ]]; then
|
||||
if [[ ! -v _ZSH_AUTOSUGGEST_DISABLED ]]; then
|
||||
zle autosuggest-clear
|
||||
fi
|
||||
fi
|
||||
|
@ -90,19 +90,19 @@ function _posh-tooltip() {
|
|||
# https://github.com/zsh-users/zsh-autosuggestions - fetch new suggestion after the space
|
||||
if [[ "$(zle -lL autosuggest-fetch)" ]]; then
|
||||
# only if suggestions not disabled (variable not set)
|
||||
if ! [[ -v _ZSH_AUTOSUGGEST_DISABLED ]]; then
|
||||
if [[ ! -v _ZSH_AUTOSUGGEST_DISABLED ]]; then
|
||||
zle autosuggest-fetch
|
||||
fi
|
||||
fi
|
||||
|
||||
# get the first word of command line as tip
|
||||
local tip=${${(MS)BUFFER##[[:graph:]]*}%%[[:space:]]*}
|
||||
# ignore an empty tip
|
||||
if [[ -z "$tip" ]]; then
|
||||
# Get the first word of command line as tip.
|
||||
local tooltip_command=${${(MS)BUFFER##[[:graph:]]*}%%[[:space:]]*}
|
||||
# Ignore an empty/repeated tooltip command.
|
||||
if [[ -z "$tooltip_command" ]] || [[ "$tooltip_command" = "$omp_tooltip_command" ]]; then
|
||||
return
|
||||
fi
|
||||
local tooltip=$(::OMP:: print tooltip --config="$POSH_THEME" --shell=zsh --status="$omp_last_error" --command="$tip" --shell-version="$ZSH_VERSION")
|
||||
# ignore an empty tooltip
|
||||
omp_tooltip_command="$tooltip_command"
|
||||
local tooltip=$(::OMP:: print tooltip --config="$POSH_THEME" --status="$omp_status_cache" --pipestatus="${omp_pipestatus_cache[*]}" --execution-time="$omp_elapsed" --stack-count="$omp_stack_count" --command="$tooltip_command" --shell=zsh --shell-version="$ZSH_VERSION" --no-status="$omp_no_exit_code")
|
||||
if [[ -z "$tooltip" ]]; then
|
||||
return
|
||||
fi
|
||||
|
@ -119,7 +119,8 @@ function _posh-zle-line-init() {
|
|||
local -i ret=$?
|
||||
(( $+zle_bracketed_paste )) && print -r -n - $zle_bracketed_paste[2]
|
||||
|
||||
eval "$(::OMP:: print transient --status="$omp_last_error" --execution-time="$omp_elapsed" --stack-count="$omp_stack_count" --config="$POSH_THEME" --eval --shell=zsh --shell-version="$ZSH_VERSION" --no-status="$no_exit_code")"
|
||||
omp_tooltip_command=''
|
||||
eval "$(::OMP:: print transient --config="$POSH_THEME" --status="$omp_status_cache" --pipestatus="${omp_pipestatus_cache[*]}" --execution-time="$omp_elapsed" --stack-count="$omp_stack_count" --eval --shell=zsh --shell-version="$ZSH_VERSION" --no-status="$omp_no_exit_code")"
|
||||
zle .reset-prompt
|
||||
|
||||
# Exit the shell if we receive EOT.
|
||||
|
|
Loading…
Reference in a new issue