mirror of
https://github.com/cmderdev/cmder.git
synced 2025-11-08 21:29:02 +08:00
Fix cmderdev/cmder#3020; hg prompt is slow.
Cmder's hg prompt didn't use async prompt filtering yet.
Cmder's svn prompt only used async prompt filtering if a special config
variable was set (the commit which contributed it seems to have
misunderstood the git config settings for the git async prompt).
This commit makes the following changes:
1. Adds async prompt filtering for hg.
2. Makes async prompt filtering for svn the default.
3. Removes the prompt_overrideSvnStatusOptIn variable.
4. Fixes a bug where any errors during `svn status` in the svn prompt
accidentally show up in the terminal.
5. Fixes a bug where any errors during `hg branch` in the hg prompt
turn into Lua errors.
6. Simplifies the code for colors in the hg and svn prompts.
7. Clean up the svn prompt code and make it consistent with the git
and hg prompt code.
This commit is contained in:
152
vendor/clink.lua
vendored
152
vendor/clink.lua
vendored
@@ -7,7 +7,7 @@
|
||||
-- luacheck: globals uah_color cwd_color lamb_color clean_color dirty_color conflict_color unknown_color
|
||||
-- luacheck: globals prompt_homeSymbol prompt_lambSymbol prompt_type prompt_useHomeSymbol prompt_useUserAtHost
|
||||
-- luacheck: globals prompt_singleLine prompt_includeVersionControl
|
||||
-- luacheck: globals prompt_overrideGitStatusOptIn prompt_overrideSvnStatusOptIn
|
||||
-- luacheck: globals prompt_overrideGitStatusOptIn
|
||||
-- luacheck: globals clink io.popenyield os.isdir settings.get
|
||||
|
||||
-- At first, load the original clink.lua file
|
||||
@@ -350,13 +350,8 @@ end
|
||||
-- @return {false|mercurial branch information}
|
||||
---
|
||||
local function get_hg_branch()
|
||||
-- Return the branch information. The default is to get just the
|
||||
-- branch name, but you could e.g. use the "hg-prompt" extension to
|
||||
-- get more information, such as any applied mq patches. Here's an
|
||||
-- example of that:
|
||||
-- local cmd = "hg prompt \"{branch}{status}{|{patch}}{update}\""
|
||||
local cmd = "hg branch 2>nul"
|
||||
local file = io.popen(cmd)
|
||||
-- Return the branch information.
|
||||
local file = io.popen("hg branch 2>nul")
|
||||
if not file then
|
||||
return false
|
||||
end
|
||||
@@ -424,12 +419,33 @@ local function get_git_status()
|
||||
return { status = is_status, conflict = conflict_found }
|
||||
end
|
||||
|
||||
---
|
||||
-- Get the status of working dir
|
||||
-- @return {bool}
|
||||
---
|
||||
local function get_hg_status()
|
||||
-- The default is to just use the branch name, but you could e.g. use the
|
||||
-- "hg-prompt" extension to get more information, such as any applied mq
|
||||
-- patches. Here's an example of that:
|
||||
-- "hg prompt \"{branch}{status}{|{patch}}{update}\""
|
||||
local pipe = io_popenyield("hg status -amrd 2>&1")
|
||||
if not pipe then
|
||||
return { error = true }
|
||||
end
|
||||
|
||||
local output = pipe:read('*all')
|
||||
pipe:close()
|
||||
|
||||
local dirty = (output ~= nil and output ~= "")
|
||||
return { clean = not dirty }
|
||||
end
|
||||
|
||||
---
|
||||
-- Get the status of working dir
|
||||
-- @return {bool}
|
||||
---
|
||||
local function get_svn_status()
|
||||
local file = io_popenyield("svn status -q")
|
||||
local file = io_popenyield("svn status -q 2>nul")
|
||||
if not file then
|
||||
return { error = true }
|
||||
end
|
||||
@@ -520,14 +536,6 @@ local function git_prompt_filter()
|
||||
return false
|
||||
end
|
||||
|
||||
-- Colors for git status
|
||||
local colors = {
|
||||
clean = get_clean_color(),
|
||||
dirty = get_dirty_color(),
|
||||
conflict = get_conflict_color(),
|
||||
nostatus = get_unknown_color()
|
||||
}
|
||||
|
||||
local git_dir = get_git_dir()
|
||||
local color
|
||||
if git_dir then
|
||||
@@ -547,18 +555,19 @@ local function git_prompt_filter()
|
||||
local gitConflict = gitInfo.conflict
|
||||
|
||||
if gitStatus == nil then
|
||||
color = colors.nostatus
|
||||
color = get_unknown_color()
|
||||
elseif gitStatus then
|
||||
color = colors.clean
|
||||
color = get_clean_color()
|
||||
else
|
||||
color = colors.dirty
|
||||
color = get_dirty_color()
|
||||
end
|
||||
|
||||
if gitConflict then
|
||||
color = colors.conflict
|
||||
color = get_conflict_color()
|
||||
end
|
||||
|
||||
clink.prompt.value = gsub_plain(clink.prompt.value, "{git}", " "..color.."("..branch..")")
|
||||
local result = " "..color.."("..branch..")"
|
||||
clink.prompt.value = gsub_plain(clink.prompt.value, "{git}", result)
|
||||
return false
|
||||
end
|
||||
end
|
||||
@@ -568,6 +577,18 @@ local function git_prompt_filter()
|
||||
return false
|
||||
end
|
||||
|
||||
local function get_hg_info_table()
|
||||
local info = clink_promptcoroutine(function ()
|
||||
return get_hg_status() or {}
|
||||
end)
|
||||
if not info then
|
||||
info = cached_info.hg_info or {}
|
||||
else
|
||||
cached_info.hg_info = info
|
||||
end
|
||||
return info
|
||||
end
|
||||
|
||||
local function hg_prompt_filter()
|
||||
|
||||
-- Don't do any hg processing if the prompt doesn't want to show hg info.
|
||||
@@ -577,33 +598,34 @@ local function hg_prompt_filter()
|
||||
|
||||
local hg_dir = get_hg_dir()
|
||||
if hg_dir then
|
||||
-- Colors for mercurial status
|
||||
local colors = {
|
||||
clean = get_clean_color(),
|
||||
dirty = get_dirty_color(),
|
||||
nostatus = get_unknown_color()
|
||||
}
|
||||
local output = get_hg_branch()
|
||||
local output = get_hg_branch() or ""
|
||||
|
||||
-- strip the trailing newline from the branch name
|
||||
local n = #output
|
||||
while n > 0 and output:find("^%s", n) do n = n - 1 end
|
||||
local branch = output:sub(1, n)
|
||||
-- strip the trailing spaces and newline from the branch name
|
||||
local branch = output:gsub("%s+$", "")
|
||||
|
||||
if branch ~= nil and
|
||||
string.sub(branch,1,7) ~= "abort: " and -- not an HG working copy
|
||||
(not string.find(branch, "is not recognized")) then -- 'hg' not in path
|
||||
local color = colors.clean
|
||||
|
||||
local pipe = io.popen("hg status -amrd 2>&1")
|
||||
if pipe then
|
||||
output = pipe:read('*all')
|
||||
pipe:close()
|
||||
if output ~= nil and output ~= "" then color = colors.dirty end
|
||||
-- If in a different repo or branch than last time, discard cached info
|
||||
if cached_info.hg_dir ~= hg_dir or cached_info.hg_branch ~= branch then
|
||||
cached_info.hg_info = nil
|
||||
cached_info.hg_dir = hg_dir
|
||||
cached_info.hg_branch = branch
|
||||
end
|
||||
|
||||
local result = color .. "(" .. branch .. ")"
|
||||
clink.prompt.value = gsub_plain(clink.prompt.value, "{hg}", " "..result)
|
||||
local hgInfo = get_hg_info_table()
|
||||
|
||||
local color
|
||||
if not hgInfo or hgInfo.error then
|
||||
color = get_unknown_color()
|
||||
elseif hgInfo.clean then
|
||||
color = get_clean_color()
|
||||
else
|
||||
color = get_dirty_color()
|
||||
end
|
||||
|
||||
local result = " "..color.."("..branch..")"
|
||||
clink.prompt.value = gsub_plain(clink.prompt.value, "{hg}", result)
|
||||
return false
|
||||
end
|
||||
end
|
||||
@@ -612,6 +634,18 @@ local function hg_prompt_filter()
|
||||
clink.prompt.value = gsub_plain(clink.prompt.value, "{hg}", "")
|
||||
end
|
||||
|
||||
local function get_svn_info_table()
|
||||
local info = clink_promptcoroutine(function ()
|
||||
return get_svn_status() or {}
|
||||
end)
|
||||
if not info then
|
||||
info = cached_info.svn_info or {}
|
||||
else
|
||||
cached_info.svn_info = info
|
||||
end
|
||||
return info
|
||||
end
|
||||
|
||||
local function svn_prompt_filter()
|
||||
|
||||
-- Don't do any svn processing if the prompt doesn't want to show svn info.
|
||||
@@ -619,13 +653,6 @@ local function svn_prompt_filter()
|
||||
return false
|
||||
end
|
||||
|
||||
-- Colors for svn status
|
||||
local colors = {
|
||||
clean = get_clean_color(),
|
||||
dirty = get_dirty_color(),
|
||||
nostatus = get_unknown_color()
|
||||
}
|
||||
|
||||
local svn_dir = get_svn_dir()
|
||||
if svn_dir then
|
||||
-- if we're inside of svn repo then try to detect current branch
|
||||
@@ -637,29 +664,16 @@ local function svn_prompt_filter()
|
||||
cached_info.svn_dir = svn_dir
|
||||
cached_info.svn_branch = branch
|
||||
end
|
||||
-- Get the svn status using coroutine if available and option is enabled. Otherwise use a blocking call
|
||||
local svnStatus
|
||||
if clink.promptcoroutine and io.popenyield and settings.get("prompt.async") and prompt_overrideSvnStatusOptIn then -- luacheck: no max line length
|
||||
svnStatus = clink_promptcoroutine(function ()
|
||||
return get_svn_status()
|
||||
end)
|
||||
-- If the status result is pending, use the cached version instead, otherwise store it to the cache
|
||||
if svnStatus == nil then
|
||||
svnStatus = cached_info.svn_info
|
||||
else
|
||||
cached_info.svn_info = svnStatus
|
||||
end
|
||||
else
|
||||
svnStatus = get_svn_status()
|
||||
end
|
||||
|
||||
local svnInfo = get_svn_info_table()
|
||||
|
||||
local color
|
||||
if not svnStatus or svnStatus.error then
|
||||
color = colors.nostatus
|
||||
elseif svnStatus.clean then
|
||||
color = colors.clean
|
||||
if not svnInfo or svnInfo.error then
|
||||
color = get_unknown_color()
|
||||
elseif svnInfo.clean then
|
||||
color = get_clean_color()
|
||||
else
|
||||
color = colors.dirty
|
||||
color = get_dirty_color()
|
||||
end
|
||||
|
||||
clink.prompt.value = gsub_plain(clink.prompt.value, "{svn}", " "..color.."("..branch..")")
|
||||
|
||||
5
vendor/cmder_prompt_config.lua.default
vendored
5
vendor/cmder_prompt_config.lua.default
vendored
@@ -38,11 +38,6 @@ prompt_includeVersionControl = true
|
||||
-- NOTE: This only takes effect if using Clink v1.2.10 or higher.
|
||||
prompt_overrideGitStatusOptIn = false
|
||||
|
||||
-- OPTIONAL. If true then always ignore the cmder.status and cmder.cmdstatus svn config settings and run the svn prompt commands in the background.
|
||||
-- default is false
|
||||
-- NOTE: This only takes effect if using Clink v1.2.10 or higher.
|
||||
prompt_overrideSvnStatusOptIn = false
|
||||
|
||||
-- Prompt Attributes
|
||||
--
|
||||
-- Colors: https://github.com/cmderdev/cmder/wiki/Customization#list-of-colors
|
||||
|
||||
Reference in New Issue
Block a user