sublime中通过内置变量$file_extension获取当前已保存文件的扩展名(不含点,小写),未保存文件返回空字符串;它在构建前由sublime自动替换,不依赖语法设置,仅取决于磁盘真实后缀。

构建系统里怎么拿到当前文件的扩展名
Sublime 的 sublime-build 文件本身不提供直接读取扩展名的变量,但可通过内置的 $file_extension 占位符获取——它不是函数,也不是运行时计算值,而是 Sublime 在构建前自动替换的环境变量。
-
$file_extension返回的是当前已保存文件的后缀(不含点),比如main.py→py;未保存的untitled文件返回空字符串 - 它只在构建命令执行前展开,不能用于条件判断或拼接逻辑(比如
"if $file_extension == 'py'"会原样传给 shell) - 若文件路径含中文或空格,
$file_extension仍安全可用,但整个$file或$file_path需用引号包裹,否则 shell 可能截断 - 注意大小写:Windows 下扩展名可能为
PY,而 Sublime 统一转为小写输出,$file_extension总是小写
为什么 $file_extension 有时为空或不对
最常见原因是文件根本没保存——$file_extension 依赖磁盘上的真实路径,untitled 缓冲区没有扩展名,自然为空。另一个容易被忽略的点是:语法高亮绑定错误会导致 Sublime 认不出文件类型,但这不影响 $file_extension,它只看物理后缀,不看语法设置。
- 打开一个未保存的文件,右下角显示
Plain Text,此时$file_extension为空 —— 这是正常行为,不是 bug - 文件保存为
config(无后缀),$file_extension也是空;想让它生效,必须显式保存为config.ini或config.env - 即使你用 ApplySyntax 插件让
.conf文件高亮为 INI,$file_extension仍是conf,不会变成ini
结合 $file_extension 写跨语言构建命令
真正实用的场景是避免为每种语言单独写一个构建系统。比如用同一个脚本分发不同后缀的处理逻辑:
{
"shell_cmd": "case \"$file_extension\" in
py) python \"$file\";
js) node \"$file\";
sh) bash \"$file\";
*) echo \"No handler for .$file_extension\";;
esac"
}
- 上面写法在 macOS/Linux 有效,Windows 的 cmd 不支持
case,得换if /I \"%FILE_EXTENSION%\"==\"py\"等等 -
$file_extension不带点,所以匹配时别写成\".py\",否则永远不命中 - 如果构建命令里要调用 Python 脚本做更复杂判断(比如识别
.yml.dist为 YAML),那就得放弃纯占位符,改用 Python 构建插件——$file_extension到此为止
别把 $file_extension 和语法绑定搞混
很多人试过改 Packages/User/Python.sublime-settings 里的 extensions 字段,以为能影响构建系统读到的扩展名。其实完全无关:$file_extension 来自文件系统,语法绑定只控制高亮、补全、缩进等编辑行为。
- 你把
.log绑定到Plain text.tmLanguage,$file_extension还是log - 你删掉所有
.sublime-syntax文件,$file_extension也不变 - 唯一能“欺骗”它的办法是重命名文件——比如把
script改成script.sh,再运行构建











