3

I know that the autocommand autocmd BufEnter will be triggered every time a buffer is entered. Is there a way to define an autocmd that will be triggered only the first time a buffer is entered?

  • Depending on your use case, BufReadPost (aka BufRead) might be an option. – Ralf May 11 '19 at 11:08
  • Do you think you could elaborate? BufReadPost and BufRead are triggered every time a buffer is read, not just the first time. – Trevor May 11 '19 at 22:40
  • But how often do you read the file into a buffer during a editing session? Maybe you should describe what you want to do. – Ralf May 12 '19 at 5:14
  • My workflow usually involves having several buffers open, and switching between them using :bn and :bp. So I'm looking for a way to execute a command when I enter a buffer that I haven't entered before. – Trevor May 13 '19 at 3:20
  • 3
    Set a buffer-local variable the first time the event triggers. Then the following times check for the existence of the variable – Christian Brabandt May 13 '19 at 6:01
2

One solution is to create a buffer-local variable the first time a buffer is entered, and then check to see if that variable exists the following times that buffer is entered:

autocmd BufEnter * if !exists('b:has_been_entered') | 
    \ let b:has_been_entered = 1 | call input('First time entered!') | endif

*note: this answer is based on this comment

| improve this answer | |
2

Based on your comment

My workflow usually involves having several buffers open, and switching between them using :bn and :bp. So I'm looking for a way to execute a command when I enter a buffer that I haven't entered before.

If you start Vim with several files, they are not read into memory immediately at startup. The file is only read when you enter the buffer.

So you can use the autocmd event "BufReadPost".

Add the following to your vimrc:

autocmd BufReadPost * echo strftime("%c")

Then open Vim with multiple existing files.

This will print a timestamp immediately on startup, as you entered the first buffer.

Then it will print a timestamp on every :bn, as you are entering a yet unvisited buffer (and it's file is read). If you use :bp to return to a file you already visited, no timestamp will be printed. Also no timestamp when you reached the end of the list and :bn brings you to the first file.

Note:

  • only works when hidden is set
  • the autocmd also fires when you reload a file (with :e)
  • is not executed for new files, as there is no file to read yet
| improve this answer | |
  • I don't think that command works as you've described. That command will print a timestamp every time you visit a buffer, whether it has been entered or not. – Trevor May 30 '19 at 22:37
  • You don't think or you tested it? – Ralf May 30 '19 at 22:49
  • I tested it. Does it work different for you? – Trevor May 30 '19 at 23:05
  • @wxyz I just retested it. Started Vim with 4 existing files and it works as I described. But it has drawbacks: If you reload a file (:e) it will fire again. Your own answer doesn't do that and also works with non-existing files. – Ralf May 31 '19 at 4:48
  • 1
    This answer only works as described if you have hidden set. With nohidden (Vim's default) the command triggers every time you switch buffer. – joeytwiddle May 31 '19 at 6:13

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.