使vim理解tcl脚本环境变量('gf'命令)

Make vim understand tcl script environment variables ('gf' command)

我经常在 vim 中使用 gf 打开光标下的文件。通常这些文件路径使用环境变量,但是在 .tcl 脚本文件中 vim 无法使用环境变量。

这适用于女友:

$tcl_lib/myfile.tcl

这些不适用于 gf:

$env(tcl_lib)/myfile.tcl
$::env(tcl_lib)/myfile.tcl

这些是我尝试过的一些方法:

:set isfname=@,48-57,/,.,-,_,+,,,#,$,%,~,=,{,},(,)
:set isfname=@,48-57,/,.,-,_,+,,,#,$,%,~,=,{,},40-41

:set includeexpr=substitute(v:fname,'$env(\([^)]\+\))','$','')

有没有办法让 vim 理解 tcl 脚本中环境变量的语法(特别是 'gf' 命令)?

有几个技巧:

设置'path'&'includeexpr'

理论上你可以在路径中添加$tcl_lib。例如set path=.,$tcl_lib,,。但是,任何以 / 开头的文件名都将失败。这可以通过删除起始 /.

来解决

添加到~/.vim/after/ftplugin/tcl.vim:

set path=.,$tcl_lib,,
let &l:includeexpr="substitute(v:fname, '^/', '', 'g')"

通过'includeexpr'

读取环境变量

可以使用替换来扩展环境变量

let l:includeexpr = "substitute(v:fname, '$\%(::\)\=env(\([^)]*\))', '\=expand(\"$\".submatch(1))', 'g')"

这使用子替换表达式(参见 :h sub-replace-expression)来使用 expand() 获取环境变量。

这可能需要您更改 'isfname' 以允许更多字符成为文件名字符串的一部分。

只需映射gf和朋友

gf<c-w>f 等创建特定于您的语言的缓冲区本地映射并检查某些路径。这完全回避了许多 Vim 的内置方法,因此它应该作为最后的手段使用。

在 ~/.vimrc 中添加以下 2 行对我有用。

set isfname+={,},(,),:
let &l:includeexpr = "substitute(v:fname,'$\%(::\)\=env(\([^)]*\))','\=expand(\"$\".submatch(1))', 'g')"

终于回到了这个问题,并且能够很好地解决它。将以下 tcl.vim 文件添加到您的 ~/.vim/ftplugin 并且您的 "gf" 应该可以工作!

https://github.com/stephenmm/dotfiles/blob/master/vim/ftplugin/tcl.vim

" Add charecters to possible filename types so vim will recognize:
"    $::env(THIS)/as/a/file.tcl
set isfname+={,},(,),:

" Turn the string into something vim knows as a filename:
"    $::env(THIS)/as/a/file.tcl => ${THIS}/as/a/file.tcl
function! TclGfIncludeExpr(fname)
  if a:fname =~? '$\(::\)\?env([^)]\+)'
    return substitute(a:fname, '$\(::\)\?env(\([^)]\+\))', '${}', 'g')
  endif
  return a:fname
endfunction

" Tie the function to includeexpr
set includeexpr=TclGfIncludeExpr(v:fname)