I have an autocommand that is supposed to register a different autocommand whenever I enter a buffer where a certain condition is met:

let w:contextlist_open = 1

augroup LaunchShowContext
    autocmd BufEnter * 
        \ if (exists("w:contextlist_open") && w:contextlist_open == 1) 
            \ | :autocmd CursorHold * call ShowContext()
        \ | endif
augroup END

If I fire up another buffer and switch back and forth, I get Error detected while processing CursorHold Autocommands for "*": E580: :endif without :if: endif. I suspect this is because Vim thinks the endif belongs with the second autocommand rather than the first, and I'm not sure how to make it so that it goes with the correct one. I tried wrapping the autocmd CursorHold * call ShowContext() in parentheses, but that seems to give me other problems.

  • 2
    I'm not sure how to make it so that it goes with the correct one Use execute. The same goes to normal, command and a few other commands. This is directly mentioned in :h :au (and also :h :normal and so on), just read it until the end. – Matt Nov 28 '19 at 5:33
  • That becomes too messy. Better just call a function, that performs your checks and quits early if they fail. – Christian Brabandt Nov 29 '19 at 7:29

Use :execute like this:

augroup LaunchShowContext | au!
    autocmd BufEnter *
        \ if get(w:, 'contextlist_open')
            \ | execute 'autocmd! CursorHold <buffer> call ShowContext()'
        \ | endif
augroup end

But note (at least) three problems:

1) You examine window-variable contextlist_open, while expecting buffer-specific event CursorHold to fire. That could be frustrating if your buffer is shown in several split windows.

2) unlet-ting contextlist_open will not remove au CursorHold, as one would expect.

3) execute will run under global augroup context, so you still must find a way to prevent repeating call ShowContext()'s due to multiple BufEnter events. I put au! for simplicity, but that could potentially conflict with other plugins, so you probably should explore another solution (create another augroup mygroup then check if exists('#mygroup#CursorHold#<buffer>') etc.).

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.