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?

8
  • Depending on your use case, BufReadPost (aka BufRead) might be an option.
    – Ralf
    May 11, 2019 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, 2019 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, 2019 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, 2019 at 3:20
  • 4
    Set a buffer-local variable the first time the event triggers. Then the following times check for the existence of the variable May 13, 2019 at 6:01

2 Answers 2

3

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

3

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
7
  • 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, 2019 at 22:37
  • You don't think or you tested it?
    – Ralf
    May 30, 2019 at 22:49
  • I tested it. Does it work different for you?
    – Trevor
    May 30, 2019 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, 2019 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. May 31, 2019 at 6:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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