在Windows上使用Anaconda(Python)+ Cmder(Clink)-统一对决自定义提示。

如果在 Windows 上运行 Anaconda,则有一个 activate.bat 文件,其中包含以下代码行,将当前的 conda env 信息放在提示符上:

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

如果在 Windows 上运行 cmder,则有一个 漂亮的 lua 脚本 来自定义您的提示符:

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

clink.prompt.register_filter(lambda_prompt_filter, 40)

这两个脚本相互之间并不太兼容。Clink 有一个 API,似乎可以用于合并 activate.bat 中的更改,但我无法弄清如何从批处理文件中调用它。

我整体的目标是将这两个提示符合并成更好的 Cmder 样式。我的想法是创建一个环境变量,修改 activate.bat 以检查变量是否存在,如果存在,则调用 Clink API 来更改提示符,而不是 set PROMPT。 在此时,我认为我可以创建一个新的过滤器,以干净地合并该值。但是,我无法弄清如何从批处理文件中调用 API。

欢迎提供其他解决方案。

编辑:部分非工作性解决方案

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)

我在提示符定义的最开始添加了一个 {conda}。从 activate.bat 中删除了提示语句,并将其添加到了 git_prompt_filter 中。在使用 activate 之前,一切正常- {conda}'' 抑制。但是,如果使用 activate 并切换到带有 git repo 的文件夹触发更改,则会看到:

{conda}C:\...

os.getenv 是否无法获取用户设置的变量?不知道问题还可能是什么。我还尝试添加了一个 print 语句,它并没有打印出 CONDA... 的内容。

点赞
用户161801
用户161801

为什么不直接从 activate.bat 中删除该行,并在 cmder 配置文件中实现所有逻辑呢?如果没有激活的环境,则 CONDA_DEFAULT_ENV 将为空。

2014-08-05 15:46:38
用户1380673
用户1380673

以下是我用于重置提示符并将 conda 环境名称添加到提示符的方法:

---
 -- 查找文件/目录的基本名称(\或/后面的最后一个元素)
 -- @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

---
 -- 查找当前的 conda 环境
 -- @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

---
 --  conda 激活后:重置提示符并添加 conda 环境名称
---
function conda_prompt_filter()
    -- 重置为原始状态,例如在 conda 激活后将销毁它...
    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
        -- 颜色代码:"\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
    -- 添加 conda 环境名称
    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)

2015-12-03 12:30:34
用户933782
用户933782

我想要在@Jan-Schulz的回答基础上进行改进,因为在2017年4月它并没有完全适用于我。

  1. 我没有编辑cmder/vendor/clink/clink.lua文件,而是将自定义代码添加到cmder/config/prompt.lua文件中,这样升级时就不会被覆盖(您也可以使用clink lua api在此文件中添加其他修改)。

  2. 我遇到了一个问题,{lamb}没有被正确替换为λ字符,所以我添加了另一个过滤器来在所有处理结束后运行。

---
 -- 获取文件/目录的基名称(\或/后的最后一个元素)
 -- @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

---
 -- 查找当前conda环境
 -- @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

---
 -- 在conda激活后:重置提示并添加conda环境名称
---
function conda_prompt_filter()
    -- 重置为原始状态,例如在conda激活后破坏它...
    if string.match(clink.prompt.value, "{lamb}") == nil then
        -- 原始:$E[1;32;40m$P$S{git}{hg}$S$_$E[1;30;40m{lamb}$S$E[0m
        -- 颜色代码:"\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
    -- 添加conda环境名称
    local conda_env = get_conda_env()
    if conda_env then
        clink.prompt.value = string.gsub(clink.prompt.value, "{lamb}", "["..conda_env.."] {lamb}")
    end
end

function fix_lamb()
    if string.match(clink.prompt.value, "{lamb}") ~= nil then
        clink.prompt.value = string.gsub(clink.prompt.value, "{lamb}", "λ")
    end
end

clink.prompt.register_filter(conda_prompt_filter, 1)
clink.prompt.register_filter(fix_lamb, 999)
2017-04-06 18:12:53