mirror of
https://github.com/cmderdev/cmder.git
synced 2024-11-10 17:59:11 +08:00
567889e69f
If having a long line of input in histroy, which went on into the second row and using <up> to get back to it, you got the effect that the input was split over three lines: "text, empty, text", but using the arrows do move to the front of the first line was moving the cursor in the second (empty) row. You could change the text, but you needed to do it "in the dark". No idea why s/os.execute/is.popen/ fixes this, but it does. Partly adresses https://github.com/cmderdev/cmder/issues/749
202 lines
6.0 KiB
Lua
202 lines
6.0 KiB
Lua
function lambda_prompt_filter()
|
|
clink.prompt.value = string.gsub(clink.prompt.value, "{lamb}", "λ")
|
|
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
|
|
-- @return {false|mercurial branch name}
|
|
---
|
|
function get_hg_branch()
|
|
for line in io.popen("hg branch 2>nul"):lines() do
|
|
local m = line:match("(.+)$")
|
|
if m then
|
|
return m
|
|
end
|
|
end
|
|
|
|
return false
|
|
end
|
|
|
|
---
|
|
-- Get the status of working dir
|
|
-- @return {bool}
|
|
---
|
|
function get_hg_status()
|
|
for line in io.popen("hg status"):lines() do
|
|
return false
|
|
end
|
|
return true
|
|
end
|
|
|
|
function hg_prompt_filter()
|
|
|
|
-- Colors for mercurial status
|
|
local colors = {
|
|
clean = "\x1b[1;37;40m",
|
|
dirty = "\x1b[31;1m",
|
|
}
|
|
|
|
if get_hg_dir() then
|
|
-- if we're inside of mercurial repo then try to detect current branch
|
|
local branch = get_hg_branch()
|
|
if branch then
|
|
-- Has branch => therefore it is a mercurial folder, now figure out status
|
|
if get_hg_status() then
|
|
color = colors.clean
|
|
else
|
|
color = colors.dirty
|
|
end
|
|
|
|
clink.prompt.value = string.gsub(clink.prompt.value, "{hg}", color.."("..branch..")")
|
|
return false
|
|
end
|
|
end
|
|
|
|
-- No mercurial present or not in mercurial file
|
|
clink.prompt.value = string.gsub(clink.prompt.value, "{hg}", "")
|
|
return false
|
|
end
|
|
|
|
---
|
|
-- Find out current branch
|
|
-- @return {nil|git branch name}
|
|
---
|
|
function get_git_branch(git_dir)
|
|
local git_dir = git_dir or get_git_dir()
|
|
|
|
-- If git directory not found then we're probably outside of repo
|
|
-- or something went wrong. The same is when head_file is nil
|
|
local head_file = git_dir and io.open(git_dir..'/HEAD')
|
|
if not head_file then return end
|
|
|
|
local HEAD = head_file:read()
|
|
head_file:close()
|
|
|
|
-- if HEAD matches branch expression, then we're on named branch
|
|
-- otherwise it is a detached commit
|
|
local branch_name = HEAD:match('ref: refs/heads/(.+)')
|
|
return branch_name or 'HEAD detached at '..HEAD:sub(1, 7)
|
|
end
|
|
|
|
---
|
|
-- Get the status of working dir
|
|
-- @return {bool}
|
|
---
|
|
function get_git_status()
|
|
return io.popen("git diff --quiet --ignore-submodules HEAD 2>nul")
|
|
end
|
|
|
|
function git_prompt_filter()
|
|
|
|
-- Colors for git status
|
|
local colors = {
|
|
clean = "\x1b[1;37;40m",
|
|
dirty = "\x1b[31;1m",
|
|
}
|
|
|
|
local git_dir = get_git_dir()
|
|
if git_dir then
|
|
-- if we're inside of git repo then try to detect current branch
|
|
local branch = get_git_branch(git_dir)
|
|
if branch then
|
|
-- Has branch => therefore it is a git folder, now figure out status
|
|
if get_git_status() then
|
|
color = colors.clean
|
|
else
|
|
color = colors.dirty
|
|
end
|
|
|
|
clink.prompt.value = string.gsub(clink.prompt.value, "{git}", color.."("..branch..")")
|
|
return false
|
|
end
|
|
end
|
|
|
|
-- No git present or not in git file
|
|
clink.prompt.value = string.gsub(clink.prompt.value, "{git}", "")
|
|
return false
|
|
end
|
|
|
|
clink.prompt.register_filter(lambda_prompt_filter, 40)
|
|
clink.prompt.register_filter(hg_prompt_filter, 50)
|
|
clink.prompt.register_filter(git_prompt_filter, 50)
|
|
|
|
local completions_dir = clink.get_env('CMDER_ROOT')..'/vendor/clink-completions/'
|
|
for _,lua_module in ipairs(clink.find_files(completions_dir..'*.lua')) do
|
|
-- Skip files that starts with _. This could be useful if some files should be ignored
|
|
if not string.match(lua_module, '^_.*') then
|
|
local filename = completions_dir..lua_module
|
|
-- use dofile instead of require because require caches loaded modules
|
|
-- so config reloading using Alt-Q won't reload updated modules.
|
|
dofile(filename)
|
|
end
|
|
end
|
|
|
|
-- now do the same for all lua files in config which do not start with '_'
|
|
local user_config_dir = clink.get_env('CMDER_ROOT')..'\\config\\'
|
|
for _,lua_module in ipairs(clink.find_files(user_config_dir..'*.lua')) do
|
|
-- Skip files that starts with _. This could be useful if some files should be ignored
|
|
if not string.match(lua_module, '^_.*') then
|
|
local filename = user_config_dir..lua_module
|
|
dofile(filename)
|
|
end
|
|
end
|