【问题标题】:Make vim understand tcl script environment variables ('gf' command)让 vim 理解 tcl 脚本环境变量('gf' 命令)
【发布时间】:2019-03-20 16:59:55
【问题描述】:

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

这适用于 gf:

$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(\([^)]\+\))','\$\1','')

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

【问题讨论】:

  • 您可以将$tcl_lib 添加到您的'path' 吗?例如setlocal path=.,$tcl_lib,,
  • @PeterRincker 我需要删除源中的“$env(tcl_lib)/”,然后源就会被破坏。
  • 理论上你可以不理会'isfname',只需将$tcl_lib添加到'path'即可。如果您更改'isfname',那么您是正确的,您需要删除或阅读$env(..) 之类的结构。
  • @PeterRincker 我确实还原了 isfname 但仍然看到开头的“/”并在根目录中查找而不是“路径”。

标签: vim tcl


【解决方案1】:

有一些技巧:

设置'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 的许多内置方法,因此应将其用作最后的手段。

【讨论】:

  • 我认为第二个非常接近,但它还不太适合我。你能解释一下它在做什么吗?特别是\% 和第一个\= 以便我可以进一步调试?顺便说一句,这确实有效:echo substitute('$::env(tcl_lib)/myfile.tcl','$\%(::\)\=env(\([^)]*\))','\=expand("$".submatch(1))','g') 所以它是带有附加引号或 let 或 ...
  • 转义已关闭。 \= 将运行一个 Vim 表达式作为替换(又名 sub-replace-expression)。
【解决方案2】:

终于回到了这个问题上,并且能够以非常好的方式解决它。将以下 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(\([^)]\+\))', '${\2}', 'g')
  endif
  return a:fname
endfunction

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

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

    • 您能edit 使用代码格式并在您的答案中给出更多解释吗?
    猜你喜欢
    • 1970-01-01
    • 2016-10-03
    • 1970-01-01
    • 1970-01-01
    • 2023-01-15
    • 1970-01-01
    • 2012-03-29
    • 2013-08-08
    • 1970-01-01
    相关资源
    最近更新 更多