Vimscript:检查子字符串时出错

kry*_*tah 3 vim gvim vimscript

我目前正在尝试将一个函数结合在一起,根据当前文件路径执行某些操作,每当我使用autocmd BufEnter更改当前缓冲区时就会触发该函数

在我的 .vimrc 中

autocmd BufEnter * call SayLocation()
Run Code Online (Sandbox Code Playgroud)


在我的 .vimrc 中再往下看

fun SayLocation()
  let str = expand("%p:~")

  if str =~ "~/dir1"
    echo "I am in dir 1!"

  elseif str =~ "~/dir2"
    echo "I am in dir 2!"

  else 
    echo "I am somewhere else"

  endif
endf
Run Code Online (Sandbox Code Playgroud)

但是,更改缓冲区会产生以下错误

第 3 行:
E33:没有先前的替代正则表达式
第 7 行:
E33:没有先前的替代正则表达式
我在其他地方


看来我运行子字符串比较器 =~ 错误。有什么线索吗?

Ing*_*kat 5

您需要转义~角色:

if str =~ '\~/dir1'
Run Code Online (Sandbox Code Playgroud)

已经:help E33很好地解释了这个问题:

E33 没有先前的替代正则表达式

在模式中使用“~”字符时,它会被“:substitute”命令中先前使用的模式替换。当尚未使用此类命令时,此操作将失败。参见|/~|。使用“:s/pat/%/”时也会发生这种情况,其中“%”代表先前的替换字符串。

额外的批评

  • 您可能希望将匹配定到开头:str =~ '^\~/dir1'。可能还会在末尾断言路径分隔符: str =~ '^\~dir1/,否则~/dir10/file也将被算作 inside dir1!
  • 匹配=~运算符(如文字==比较)遵循'ignorecase'设置。因此,建议通过 或 使比较独立于该选项的当前=~#=~?
  • 除非您需要使用特殊的键符号,否则最好使用单引号'string',因为反斜杠在那里没有特殊含义,不需要转义(再次)。
  • 你应该把你的包裹:autocmd在一个:augroup;中 如果没有它,每次重新加载~/.vimrc都会添加另一个运行:
augroup SayLocation
    autocmd! " Clear existing
    autocmd BufEnter * ...
augroup END
Run Code Online (Sandbox Code Playgroud)