Open Tset-Noitamotua opened 7 years ago
Hi @Tset-Noitamotua This looks promising!
You can register a function as a filter and assign it a rank, and Clink (which Cmder uses in the background) will apply this filter to the prompt. See this line in the powerline_prompt.lua
file.
clink.prompt.register_filter(colorful_git_prompt_filter, 60)
Here colorful_git_prompt_filter
is the function, and 60
is the rank.
This way you can create one lua
file for each group of filter that are related, and choose to apply them as you want. To activate a lua
file, just place it in the %CMDER_ROOT%/config
folder.
I'll try it.
What is the rank for? Is it kind of a prioraty to which filter will apply?
yep yep yep
(... font is missing on my recent machine)
powerline_venv_prompt.lua
-- Resets the prompt
function lambda_prompt_filter()
cwd = clink.get_cwd()
prompt = "\x1b[37;44m{cwd} {git}{hg}\n\x1b[1;30;40m{lamb} \x1b[0m"
new_value = string.gsub(prompt, "{cwd}", cwd)
clink.prompt.value = string.gsub(new_value, "{lamb}", "λ")
end
--- copied from clink.lua
-- 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
-- copied from clink.lua
-- clink.lua is saved under %CMDER_ROOT%\vendor
local function get_hg_dir(path)
return get_dir_contains(path, '.hg')
end
-- adopted from clink.lua
-- clink.lua is saved under %CMDER_ROOT%\vendor
function colorful_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
-- copied from clink.lua
-- clink.lua is saved under %CMDER_ROOT%\vendor
local function get_git_dir(path)
-- 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
-- Checks if provided directory contains git directory
local function has_git_dir(dir)
return #clink.find_dirs(dir..'/.git') > 0 and dir..'/.git'
end
local function has_git_file(dir)
local gitfile = io.open(dir..'/.git')
if not gitfile then return false end
local git_dir = gitfile:read():match('gitdir: (.*)')
gitfile:close()
return git_dir and dir..'/'..git_dir
end
-- Set default path to current directory
if not path or path == '.' then path = clink.get_cwd() end
-- Calculate parent path now otherwise we won't be
-- able to do that inside of logical operator
local parent_path = pathname(path)
return has_git_dir(path)
or has_git_file(path)
-- Otherwise go up one level and make a recursive call
or (parent_path ~= path and get_git_dir(parent_path) or nil)
end
---
-- Get the status of working dir
-- @return {bool}
---
function get_git_status()
return os.execute("git diff --quiet --ignore-submodules HEAD")
end
-- adopted from clink.lua
-- Modified to add colors and arrow symbols
function colorful_git_prompt_filter()
-- Colors for git status
local colors = {
clean = "\x1b[34;42m\x1b[37;42m ",
dirty = "\x1b[34;43m\x1b[30;43m ",
}
local closingcolors = {
clean = " \x1b[32;40m",
dirty = "± \x1b[33;40m",
}
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
closingcolor = closingcolors.clean
else
color = colors.dirty
closingcolor = closingcolors.dirty
end
clink.prompt.value = string.gsub(clink.prompt.value, "{git}", color.." "..branch..closingcolor)
return false
end
end
-- No git present or not in git file
clink.prompt.value = string.gsub(clink.prompt.value, "{git}", "\x1b[34;40m")
return false
end
---
-- add virtual env name
---
function venv_prompt_filter()
-- add in virtual env name
local venv = get_virtual_env('VIRTUAL_ENV')
if venv then
clink.prompt.value = string.gsub(clink.prompt.value, "λ", "["..venv.."] λ")
end
end
-- override the built-in filters
clink.prompt.register_filter(lambda_prompt_filter, 55)
clink.prompt.register_filter(colorful_hg_prompt_filter, 60)
clink.prompt.register_filter(colorful_git_prompt_filter, 60)
clink.prompt.register_filter(venv_prompt_filter, 65)
Thanke You!
Cheers Tset
... if I just could code as good as this looks - damn it!!! :-)))
Font name is (in case somebody cares) Roboto Mono Medium for Powerline
, Size 14, Anti-aliasing=ClearType
That's great @Tset-Noitamotua I suggest that this becomes its own plugin in a separate repo. This way, those who are interested in the Git integration get that only, and those interested in Python integration get that only. See the README for this project on how to easily install a plugin.
I did a fork. New repo is here: cmder-powerline-venv-prompt
Cheers Tset
@AmrEldib can we link out to their repository in the readme.md here?
Hi, I tried your solution @Tset-Noitamotua but unfortunately when I'm activating any of the virtualenvs I get this:
\powerline_venv_prompt.lua:193: attempt to index global 'exports' (a nil value)
Any idea what might be causing it?
Up with JorgeGRC, debugging right now.
@JorgeGRC Did you ever figure out the cause? I can't seem to find the exports variable in any of the .lua
files.
Fixed my issue. For anyone who may be running into the attempt to index global 'exports' (a nil value)
. It seems that exports.basename(path)
is a global function created in the cmder/vendor/clink-completions/modules/path.lua
. I simple copied the function and modified it to be a locally defined function within the cmder/config/powerline_venv_prompt.lua
file. Below are the two solutions I have found:
Solution 1:
Add local exports = require('path')
into the cmder/config/powerline_venv_prompt.lua
file.
Solution 2:
Insert this code below in the the cmder/config/powerline_venv_prompt.lua
file to create a locally defined basename
function.
function basename(path)
local prefix = path
local i = path:find("[\\/:][^\\/:]*$")
if i then
prefix = path:sub(i + 1)
end
return prefix
end
Then modify the line which is set to access the function as written here in the same filebasen = exports.basename(env_path)
and replace it with basen = basename(env_path)
.
I'm sure there is another solution to the issue which seems to be causing the script to not be able to access the path.lua
script which sets the exports object, but either of these fixed the issue for myself.
so if cmder supports showing env's by default, and powerline breaks this feature and this enhancement no longer works... what is the proper solution?
this is my solution for conda
local function get_py_env(env_var)
env = clink.get_env(env_var)
if env then
return env
end
return false
end
local function get_conda_env_filter()
local env = get_py_env("CONDA_DEFAULT_ENV")
if env then
env = addTextWithColor("", env.." ", ansiFgClrYellow, ansiBgClrBlack)
clink.prompt.value = string.gsub(clink.prompt.value, plc_prompt_lambSymbol, env..plc_prompt_lambSymbol)
end
return false
end
clink.prompt.register_filter(get_conda_env_filter, 100)
Is there a way to add virtualenv next to the git as another prompt module?
Also anyone have a working solution for pipenv (without the hash values)
So, Is this something that could work with the portable version?
I have not tested it with the portable version.
Josh Chrestman notifications@github.com schrieb am Di., 2. Apr. 2019, 17:30:
So, Is this something that could work with the portable version?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/AmrEldib/cmder-powerline-prompt/issues/5#issuecomment-479052160, or mute the thread https://github.com/notifications/unsubscribe-auth/AFX9hv681Pd-TCotBiGeafsyT6rIK641ks5vc3d0gaJpZM4LZ5xN .
@Tset-Noitamotua A simple creation of the pyenv_prompt_config.lua didn't do anything. No errors, and the env seems to have been activated, but theres no change in the console.
Im also using activate
Me, too have no clue about lua :-) maybe the maintainer of the repo I forked from can help you.
Actually I switched to Linux cause I was tired of all the extra steps needed when it comes to setup all the cool stuff. It was always like: u see something cool on Mac or Linux then have to go and find a workaround to achive the same on Windows :-(
Josh Chrestman notifications@github.com schrieb am Di., 2. Apr. 2019, 17:42:
@Tset-Noitamotua https://github.com/Tset-Noitamotua A simple creation of the pyenv_prompt_config.lua didn't do anything. No errors, and the env seems to have been activated, but theres no change in the console.
Im also using activate
rather than workon... not sure if clink cares about that? Very unfamiliar with all this lua config. — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/AmrEldib/cmder-powerline-prompt/issues/5#issuecomment-479058769, or mute the thread https://github.com/notifications/unsubscribe-auth/AFX9hktI6EQEatqpAqU_0I-J6sbMxQcnks5vc3pwgaJpZM4LZ5xN .
I have used below code (in file
C:\tools\cmder\config\pyenv_prompt_config.lua
) to display which virtual python env is activated. It's not my code, I have found it on Github or Stackoverflow and I have no clue about Lua :(Could it be combined somehow with your cmder-powerline-prompt?
Thats how it looked:
Cheers Tset