fix: async prompt for cmd

This commit is contained in:
Jan De Dobbeleer 2022-03-08 07:42:46 +01:00 committed by Jan De Dobbeleer
parent b0be123b1f
commit f7d33b1deb

View file

@ -3,18 +3,30 @@
local endedit_time
local last_duration
local tip_word
local cached_prompt = {}
local function omp_exe()
return [["::OMP::"]]
end
local function omp_config()
return [[::CONFIG::]]
return [["::CONFIG::"]]
end
local function can_async()
if (clink.version_encoded or 0) >= 10030001 then
return settings.get("prompt.async")
end
end
local function run_posh_command(command)
command = '"'..command..'"'
output = io.popen(command):read("*a")
local _,ismain = coroutine.running()
if ismain then
output = io.popen(command):read("*a")
else
output = io.popenyield(command):read("*a")
end
return output
end
@ -62,27 +74,66 @@ local function error_level_option()
end
local function get_posh_prompt(rprompt)
local prompt_exe = string.format('%s --shell=cmd --config="%s" %s %s --rprompt=%s', omp_exe(), omp_config(), execution_time_option(), error_level_option(), rprompt)
local prompt_exe = string.format('%s --shell=cmd --config=%s %s %s --rprompt=%s', omp_exe(), omp_config(), execution_time_option(), error_level_option(), rprompt)
return run_posh_command(prompt_exe)
end
local function get_posh_tooltip(command)
local prompt_exe = string.format('%s --shell=cmd --config=%s --command="%s"', omp_exe(), omp_config(), command)
local tooltip = run_posh_command(prompt_exe)
if tooltip == "" then
-- If no tooltip, generate normal rprompt.
tooltip = get_posh_prompt(true)
end
return tooltip
end
local p = clink.promptfilter(1)
function p:filter(prompt)
return get_posh_prompt(false)
if cached_prompt.left and cached_prompt.tip_space then
-- Use the cached left prompt when updating the rprompt (tooltip) in
-- response to the Spacebar. This allows typing to stay responsive.
else
-- Generate the left prompt normally.
cached_prompt.left = get_posh_prompt(false)
end
return cached_prompt.left
end
function p:rightfilter(prompt)
if tip_word == nil then
return get_posh_prompt(true), false
-- No tooltip needed, so generate prompt normally.
cached_prompt.right = get_posh_prompt(true)
elseif cached_prompt.tip_space and can_async() then
-- Generate tooltip asynchronously in response to Spacebar.
if cached_prompt.coroutine then
-- Coroutine is already in progress. The cached right prompt will
-- be used until the coroutine finishes.
else
-- Create coroutine to generate tooltip rprompt.
cached_prompt.coroutine = coroutine.create(function ()
cached_prompt.right = get_posh_tooltip(tip_word)
cached_prompt.tip_done = true
-- Refresh the prompt once the tooltip is generated.
clink.refilterprompt()
end)
end
if cached_prompt.tip_done then
-- Once the tooltip is ready, clear the Spacebar flag so that if the
-- command word changes and the Spacebar is pressed again, we can
-- generate a new tooltip.
cached_prompt.tip_done = nil
cached_prompt.tip_space = nil
cached_prompt.coroutine = nil
end
else
-- Tooltip is needed, but not in response to Spacebar, so refresh it
-- immediately.
cached_prompt.right = get_posh_tooltip(tip_word)
end
local prompt_exe = string.format('%s --shell=cmd --config="%s" --command="%s"', omp_exe(), omp_config(), tip_word)
tooltip = run_posh_command(prompt_exe)
if tooltip ~= "" then
return tooltip, false
end
return get_posh_prompt(true), false
return cached_prompt.right, false
end
function p:transientfilter(prompt)
local prompt_exe = string.format('%s --shell=cmd --config="%s" --print-transient', omp_exe(), omp_config())
local prompt_exe = string.format('%s --shell=cmd --config=%s --print-transient', omp_exe(), omp_config())
prompt = run_posh_command(prompt_exe)
if prompt == "" then
prompt = nil
@ -116,11 +167,12 @@ function ohmyposh_space(rl_buffer)
local words = string.explode(rl_buffer:getbuffer(), ' ', [["]])
if words[1] ~= tip_word then
tip_word = words[1] -- remember the first word for use when filtering the prompt
cached_prompt.tip_space = can_async()
clink.refilterprompt() -- invoke the prompt filters so omp can update the prompt per the tip word
end
end
if rl.setbinding then
clink.onbeginedit(function () tip_word = nil end)
clink.onbeginedit(function () tip_word = nil cached_prompt = {} end)
rl.setbinding(' ', [["luafunc:ohmyposh_space"]], 'emacs')
end