3

I am currently trying to tie together a function to do something depending on current file path, triggered whenever I change the current buffer with autocmd BufEnter

In my .vimrc

autocmd BufEnter * call SayLocation()


Further down in my .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

However, changing the buffer yields the following error

Line 3:
E33: No previous substitute regular expression
Line 7:
E33: No previous substitute regular expression
I am somewhere else


It seems I am running the substring comparator =~ wrong. Any clue?

krystah
  • 1,697

1 Answers1

5

You need to escape the ~ character:

if str =~ '\~/dir1'

The :help E33 already explains the problem very well:

E33 No previous substitute regular expression

When using the '~' character in a pattern, it is replaced with the previously used pattern in a ":substitute" command. This fails when no such command has been used yet. See |/~|. This also happens when using ":s/pat/%/", where the "%" stands for the previous substitute string.

Additional critique

  • You probably want to anchor the match to the beginning: str =~ '^\~/dir1'. Probably also assert a path separator at the end: str =~ '^\~dir1/, or else ~/dir10/file would also be counted as inside dir1!
  • The =~ match operator (like the literal == comparison) obeys the 'ignorecase' setting. Therefore, it is advisable to make the comparison independent of that option's current value via either =~# or =~?.
  • Unless you need to use special key-notation, it's better to use single-quoted 'string', because the backslash has no special meaning there and doesn't need to be escaped (once more).
  • You should wrap your :autocmd in an :augroup; without it, each reload of ~/.vimrc will add another run:
augroup SayLocation
    autocmd! " Clear existing
    autocmd BufEnter * ...
augroup END
Ingo Karkat
  • 23,523