Spaceship 的 Elixir 段:Elixir 版本识别、版本管理器集成与默认版本过滤机制
【免费下载链接】spaceship-prompt🚀✨ Minimalistic, powerful and extremely customizable Zsh prompt项目地址: https://gitcode.com/gh_mirrors/sp/spaceship-prompt
elixir段是 Spaceship(一款极简、强大且高度可定制的 Zsh 提示符)中用于在 Elixir 项目目录下展示当前 Elixir 解释器版本的提示符段。它默认异步渲染,仅在包含mix.exs或.ex/.exs文件的目录中生效,并内置了对 kiex、exenv、asdf 等版本管理器的识别能力;通过SPACESHIP_ELIXIR_DEFAULT_VERSION变量还可以将某个"默认版本"(例如系统自带版本)从提示符中隐藏。读完本文,你可以完整理解该段的显示条件、全部配置参数、版本探测的优先级链,以及在 sections/elixir.zsh 中的实现细节。
显示条件:什么目录下才会出现 Elixir 段
elixir段显示的是当前环境的Elixir 版本号。它并不是在每个目录都渲染,而是只在当前目录满足以下任一条件时才出现:
- 目录中包含
mix.exs文件(Mix 项目的入口文件); - 目录中包含任意其他
.ex或.exs扩展名的文件。
这个"仅针对 Elixir 专属目录"的判断直接写在段函数的入口逻辑中,见 sections/elixir.zsh:
spaceship_elixir() { [[ $SPACESHIP_ELIXIR_SHOW == false ]] && return # Show versions only for Elixir-specific folders [[ -f mix.exs || -n *.ex(#qN^/) || -n *.exs(#qqN^/) ]] || return ...从源码结构看,这里使用了 zsh 的 glob 修饰符(#q表示不区分大小写,^/表示排除目录)来检查当前目录是否存在.ex/.exs文件。只要三个条件都不满足,函数立即return,提示符中不会出现该段。
另外,SPACESHIP_ELIXIR_SHOW=false可以在任何情况下彻底关闭该段。
版本探测:kiex、exenv、asdf 与原生 elixir 的优先级链
elixir段的核心价值在于:它能感知多种 Elixir 版本管理器,并自动选出"当前目录实际生效"的版本。探测逻辑按以下优先级依次执行(sections/elixir.zsh):
- kiex:若系统中安装了
kiex,直接读取环境变量ELIXIR_VERSION(kiex 会维护该变量记录当前激活版本),零额外开销; - exenv:若安装了
exenv,执行exenv version-name获取当前版本名; - asdf:若安装了
asdf,执行asdf current --no-header elixir,并取输出的第二个字段(即版本名); - 回退到原生命令:以上均未命中时,检查
elixir命令是否存在(借助工具函数 lib/utils.zsh 中的spaceship::exists,其本质是command -v),再执行elixir -v,通过grep "Elixir" | cut -d ' ' -f 2提取版本号。grep调用同样走 lib/utils.zsh 中封装的spaceship::grep,用于屏蔽颜色输出等干扰。
几个值得注意的边界处理:
- 若探测结果
elixir_version仍为空(例如目录有 Elixir 文件但系统根本没有 Elixir 工具链),函数直接返回,不渲染该段; - 若版本值为字符串
system(asdf 表示使用系统版本的约定),同样直接隐藏——这符合提示符"只显示有意义的非默认信息"的设计取向; - 若版本等于
SPACESHIP_ELIXIR_DEFAULT_VERSION指定的值,也直接隐藏(见下文)。
设置默认版本:隐藏系统自带 Elixir
如果你不希望某个特定版本(例如随系统安装的 Elixir)在提示符中刷屏,可以设置SPACESHIP_ELIXIR_DEFAULT_VERSION。当探测到的当前版本与该变量相等时,段会被隐藏。在~/.zshrc中配置:
SPACESHIP_ELIXIR_DEFAULT_VERSION="1.13.4"对应实现为 sections/elixir.zsh 中的两行短路判断:
[[ $elixir_version == "system" ]] && return [[ $elixir_version == $SPACESHIP_ELIXIR_DEFAULT_VERSION ]] && return该变量默认值为空字符串(sections/elixir.zsh),即不设置时不过滤任何版本。
配置参数总览
elixir段支持以下环境变量(默认值以源码 sections/elixir.zsh 为准):
| 变量 | 默认值 | 说明 |
|---|---|---|
SPACESHIP_ELIXIR_SHOW | true | 是否显示该段 |
SPACESHIP_ELIXIR_ASYNC | true | 是否异步渲染该段 |
SPACESHIP_ELIXIR_PREFIX | $SPACESHIP_PROMPT_DEFAULT_PREFIX | 段前缀 |
SPACESHIP_ELIXIR_SUFFIX | $SPACESHIP_PROMPT_DEFAULT_SUFFIX | 段后缀 |
SPACESHIP_ELIXIR_DEFAULT_VERSION | (空) | 视为默认版本、需隐藏的 Elixir 版本号 |
SPACESHIP_ELIXIR_SYMBOL | 💧 | 段前方的符号 |
SPACESHIP_ELIXIR_COLOR | magenta | 段的颜色 |
示例配置(~/.zshrc):
# 关闭 Elixir 段 SPACESHIP_ELIXIR_SHOW=false # 改为同步渲染(一般不建议,异步可避免每次提示符卡顿) SPACESHIP_ELIXIR_ASYNC=false # 自定义颜色与符号 SPACESHIP_ELIXIR_COLOR="green" SPACESHIP_ELIXIR_SYMBOL="🐍 "关于异步渲染
文档特别标注:该段默认异步渲染(SPACESHIP_ELIXIR_ASYNC默认为true)。从源码结构看,提示符框架在 lib/utils.zsh 的spaceship::is_section_async中统一判断某段是否异步:elixir不在必须同步渲染的固定段列表(user、dir、host、exec_time、async、line_sep、jobs、exit_code、char)中,因此它遵循"全局SPACESHIP_PROMPT_ASYNC为true且段级SPACESHIP_ELIXIR_ASYNC为true时异步"的规则。异步的意义在于:版本探测涉及执行外部命令(exenv、asdf current、elixir -v等),放到后台执行可以避免阻塞提示符刷新,elixir段的版本探测成本在提示符所有段中属于较高一档,因此默认异步是合理的。
渲染细节:版本号前缀与段打包
版本号确定后,源码会做一次格式规整(sections/elixir.zsh):
# Add 'v' before elixir version that starts with a number [[ "${elixir_version}" =~ ^[0-9].+$ ]] && elixir_version="v${elixir_version}"即:如果版本以数字开头(如1.13.4),自动补上v前缀显示为v1.13.4;而已经是v开头或非纯数字开头(如版本管理器给出的别名)则原样输出。
最终通过spaceship::section将段的颜色、前缀、后缀、符号与内容打包输出:
spaceship::section \ --color "$SPACESHIP_ELIXIR_COLOR" \ --prefix "$SPACESHIP_ELIXIR_PREFIX" \ --suffix "$SPACESHIP_ELIXIR_SUFFIX" \ --symbol "$SPACESHIP_ELIXIR_SYMBOL" \ "$elixir_version"spaceship::section的实现见 lib/section.zsh:它把color/prefix/suffix/symbol/content拼成一个以·|·为分隔符的元组字符串输出,稍后由 lib/section.zsh 中的spaceship::section::render解析并渲染成带颜色(%F{...})、加粗前缀/后缀的最终提示符片段。magenta颜色与💧符号就是这一渲染流程中--color与--symbol参数的默认取值。
相关文档
- 英文版对应文档:docs/sections/elixir.md;乌克兰语版(本文参考文档):docs/uk/sections/elixir.md
- 段实现源码:sections/elixir.zsh
- 工具函数(
spaceship::exists、spaceship::grep、异步判定):lib/utils.zsh - 段打包与渲染:lib/section.zsh
- 段注册位置:spaceship.zsh 中的默认段列表包含
elixir
适用前提与限制:本文描述的行为以当前仓库代码为准。该段依赖 Elixir 工具链(elixir命令或 kiex/exenv/asdf 之一)存在;在完全没有 Elixir 环境的机器上,即使目录满足文件条件,段也不会显示(探测结果为空时直接返回)。
【免费下载链接】spaceship-prompt🚀✨ Minimalistic, powerful and extremely customizable Zsh prompt项目地址: https://gitcode.com/gh_mirrors/sp/spaceship-prompt
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考