Improve performance of git and mercurial prompt

This implements custom logic to detect if we're inside of working tree
and skips os calls if not. This will improve performance of prompt
handling, especially for mercurial prompt.
This commit is contained in:
Vladimir Kotikov 2015-03-22 00:42:01 +03:00
parent 522a75835f
commit d8c9d32cb2

View File

@ -2,6 +2,65 @@ function lambda_prompt_filter()
clink.prompt.value = string.gsub(clink.prompt.value, "{lamb}", "λ") clink.prompt.value = string.gsub(clink.prompt.value, "{lamb}", "λ")
end end
---
-- Resolves closest directory location for specified directory.
-- Navigates subsequently up one level and tries to find specified directory
-- @param {string} path Path to directory will be checked. If not provided
-- current directory will be used
-- @param {string} dirname Directory name to search for
-- @return {string} Path to specified directory or nil if such dir not found
local function get_dir_contains(path, dirname)
-- return parent path for specified entry (either file or directory)
local function pathname(path)
local prefix = ""
local i = path:find("[\\/:][^\\/:]*$")
if i then
prefix = path:sub(1, i-1)
end
return prefix
end
-- Navigates up one level
local function up_one_level(path)
if path == nil then path = '.' end
if path == '.' then path = clink.get_cwd() end
return pathname(path)
end
-- Checks if provided directory contains git directory
local function has_specified_dir(path, specified_dir)
if path == nil then path = '.' end
local found_dirs = clink.find_dirs(path..'/'..specified_dir)
if #found_dirs > 0 then return true end
return false
end
-- Set default path to current directory
if path == nil then path = '.' end
-- If we're already have .git directory here, then return current path
if has_specified_dir(path, dirname) then
return path..'/'..dirname
else
-- Otherwise go up one level and make a recursive call
local parent_path = up_one_level(path)
if parent_path == path then
return nil
else
return get_dir_contains(parent_path, dirname)
end
end
end
local function get_hg_dir(path)
return get_dir_contains(path, '.hg')
end
local function get_git_dir(path)
return get_dir_contains(path, '.git')
end
--- ---
-- Find out current branch -- Find out current branch
-- @return {false|mercurial branch name} -- @return {false|mercurial branch name}
@ -36,18 +95,20 @@ function hg_prompt_filter()
dirty = "\x1b[31;1m", dirty = "\x1b[31;1m",
} }
local branch = get_hg_branch() if get_hg_dir() then
if branch then -- if we're inside of mercurial repo then try to detect current branch
-- Has branch => therefore it is a mercurial folder, now figure out status local branch = get_hg_branch()
if get_hg_status() then if branch then
color = colors.clean -- Has branch => therefore it is a mercurial folder, now figure out status
else if get_hg_status() then
color = colors.dirty color = colors.clean
end else
color = colors.dirty
end
clink.prompt.value = string.gsub(clink.prompt.value, "{hg}", color.."("..branch..")") clink.prompt.value = string.gsub(clink.prompt.value, "{hg}", color.."("..branch..")")
clink.prompt.value = string.gsub(clink.prompt.value, "{git}", "") return false
return true end
end end
-- No mercurial present or not in mercurial file -- No mercurial present or not in mercurial file
@ -86,18 +147,20 @@ function git_prompt_filter()
dirty = "\x1b[31;1m", dirty = "\x1b[31;1m",
} }
local branch = get_git_branch() if get_git_dir() then
if branch then -- if we're inside of git repo then try to detect current branch
-- Has branch => therefore it is a git folder, now figure out status local branch = get_git_branch()
if get_git_status() then if branch then
color = colors.clean -- Has branch => therefore it is a git folder, now figure out status
else if get_git_status() then
color = colors.dirty color = colors.clean
end else
color = colors.dirty
end
clink.prompt.value = string.gsub(clink.prompt.value, "{git}", color.."("..branch..")") clink.prompt.value = string.gsub(clink.prompt.value, "{git}", color.."("..branch..")")
clink.prompt.value = string.gsub(clink.prompt.value, "{hg}", "") return false
return true end
end end
-- No git present or not in git file -- No git present or not in git file