Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Anaconda (Python) + Cmder (Clink) on Windows - Unify Dueling Custom Prompts

If you run Anaconda on windows, you have an activate.bat file which concludes with this line to put your current conda env on the prompt:

set PROMPT=[%CONDA_DEFAULT_ENV%] $P$G

If you run cmder on windows, there is a nice lua script to customize your prompt:

function lambda_prompt_filter()
    clink.prompt.value = string.gsub(clink.prompt.value, "{lamb}", "λ")
end

clink.prompt.register_filter(lambda_prompt_filter, 40)

These two scripts do not play very nicely with each other. Clink has an API that seems like I could use to incorporate the change from activate.bat, but I cannot figure out how to call it from a batch file.

My overall goal is to merge these two prompts into the nicer Cmder-style. My thought is to create an environment variable, change activate.bat to check for the existence of the variable, and, if so, call the Clink API to change the prompt instead of set PROMPT. At that point I would think I could create a new filter to cleanly merge the value in. I can't figure out how to call the API from the batch file, though.

Other solutions welcome.

EDIT: Partial, non-working solution

require "os" -- added to top of file, rest in filter function
local sub = os.getenv("CONDA_DEFAULT_ENV")
if sub == nil then
    sub = ""
end
print(sub)
clink.prompt.value = string.gsub(clink.prompt.value, "{conda}", sub)

I added a {conda} in the prompt definition at the very beginning; removed the prompt statement from activate.bat, and added this to git_prompt_filter. Prior to using activate, everything is fine - the {conda} gets suppressed by the ''. However, if I use activate and switch into a folder with a git repo to trigger the change, I see:

{conda}C:\...

Does os.getenv not get user set variables? Don't know what else the problem would be. I also tried adding a print, it doesn't print out the contents of CONDA... either.

like image 479
schodge Avatar asked Aug 04 '14 19:08

schodge


1 Answers

This is what I do to reset the prompt and add the conda env name to the prompt:

---
 -- Find out the basename of a file/directory (last element after \ or /
 -- @return {basename}
---
function basename(inputstr)
        sep = "\\/"
        local last = nil
        local t={} ; i=1
        for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
                --t[i] = str
                --i = i + 1
                last = str
        end
        return last
end

---
 -- Find out current conda env
 -- @return {false|conda env name}
---
function get_conda_env()
    env_path = clink.get_env('CONDA_DEFAULT_ENV')
    if env_path then
        basen = basename(env_path)
        return basen
    end
    return false
end

---
 -- after conda activate: reset prompt and add conda env name 
---
function conda_prompt_filter()
    -- reset to original, e.g. after conda activate destroyed it...
    if string.match(clink.prompt.value, "{lamb}") == nil then
        -- orig: $E[1;32;40m$P$S{git}{hg}$S$_$E[1;30;40m{lamb}$S$E[0m
        -- color codes: "\x1b[1;37;40m"
        cwd = clink.get_cwd()
        prompt = "\x1b[1;32;40m{cwd} {git}{hg} \n\x1b[1;30;40m{lamb} \x1b[0m"
        new_value = string.gsub(prompt, "{cwd}", cwd)
        clink.prompt.value = new_value
    end
    -- add in conda env name
    local conda_env = get_conda_env()
    if conda_env then
        clink.prompt.value = string.gsub(clink.prompt.value, "{lamb}", "["..conda_env.."] {lamb}")
    end
end

clink.prompt.register_filter(conda_prompt_filter, 10)
like image 136
Jan Katins Avatar answered Sep 27 '22 16:09

Jan Katins