【问题标题】:Anaconda (Python) + Cmder (Clink) on Windows - Unify Dueling Custom PromptsWindows 上的 Anaconda (Python) + Cmder (Clink) - 统一决斗自定义提示
【发布时间】:2014-08-04 19:13:34
【问题描述】:

如果您在 Windows 上运行 Anaconda,您有一个 activate.bat 文件,该文件以这一行结尾,以将您当前的 conda env 放在提示符上:

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

如果你在windows上运行cmder,有一个nice lua script可以自定义你的提示:

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

clink.prompt.register_filter(lambda_prompt_filter, 40)

这两个脚本不能很好地相互配合。 Clink has an 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。在使用激活之前,一切都很好 - {conda}'' 抑制。但是,如果我使用 activate 并切换到带有 git repo 的文件夹来触发更改,我会看到:

{conda}C:\...

os.getenv 不获取用户设置变量吗?不知道还有什么问题。我也尝试添加打印,它也不会打印出CONDA...的内容。

【问题讨论】:

标签: batch-file lua command-prompt anaconda conda


【解决方案1】:

这是我重置提示并将 conda env 名称添加到提示的操作:

---
 -- 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)

【讨论】:

    【解决方案2】:

    我想以 @Jan-Schulz 的回答为基础,因为它在 2017 年 4 月并不完全适合我。

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

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

    ---
     -- 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
    
    
    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)
    

    【讨论】:

      【解决方案3】:

      为什么不直接从activate.bat 中删除该行并在您的cmder 配置文件中执行所有逻辑?如果没有环境处于活动状态,则 CONDA_DEFAULT_ENV 将为空。

      【讨论】:

      • 我期待从激活中删除该行,但试图弄清楚我如何(而不是)从批处理文件中调用 Clink API 以让它知道更新提示。您是否建议始终在 CONDA_DEFAULT_ENV 中提示提示?我原以为 lambda_prompt_filter() 只调用一次来设置提示,但再看一遍,可能每次显示提示时都会调用它。将进行调查。
      • 即使不是每次都设置,您应该希望每次都能取消引用环境变量。
      • 顺便说一句,希望未来版本的 conda 将像在 OS X 和 Linux 上一样在 Windows 上使用 changeps1 选项,允许您通过配置设置禁用该行。我们没有足够多的 Windows 专家来处理它,无法给予它应得的爱(但欢迎拉取请求)。
      • 我已经让这个几乎可以工作了,但是 Windows 上 Lua 中的 os.getenv() 似乎没有获得用户特定的变量。见上文。
      猜你喜欢
      • 1970-01-01
      • 2019-07-24
      • 1970-01-01
      • 1970-01-01
      • 2019-06-17
      • 2018-06-26
      • 1970-01-01
      • 2019-06-21
      • 1970-01-01
      相关资源
      最近更新 更多