9

Here is how I reproduce the behavior I am observing.

First, I enter this command:

echo aaaaa > a
vim a

In Vim, I enter these commands:

:ls
:e #
:echo bufname('#')

Here is the output of the above three commands:

:ls
  1 %a   "a"                            line 1

:e #
E194: No alternate file name to substitute for '#'

:echo bufname('#')

The bufname('#') command produces no output.

Now I enter this command:

:bd #

The current buffer is deleted and it is replaced with a "[No Name]" buffer:

:ls
  2 %a   "[No Name]"                    line 1

I was expecting to get the E194 error on executing :bd #. Why did it delete the current buffer instead?

I am using VIM - Vi IMproved 8.0.

  • 1
    That is an interesting point. You can mention in your question that this is also the case in NVIM v0.3.0-dev, I checked. – klaus Jun 3 '18 at 7:12
  • @LoneLearner I didn't really answer this because of the bounty but if you're going to offer one it would be nice if you'd award it to a deserving answer...alas, you haven't logged in in almost a week and the bounty period is over... – B Layer Jun 12 '18 at 14:08
7

Evidence

Because there is no alternate file you're actually just running plain ol' :bd, deleting the current buffer...try it without # and you'll see the result is the same. A similar thing happens with :buffer, :sbuffer and at least a couple other commands that accept # as an argument: they silently behave as if no arguments were passed.

Along the same lines, if you try :bunload # you get this error: E90: Cannot unload last buffer. Run :bunload with no arguments and, once again, you'll get the same result.

The Docs

So we have evidence that # is being replaced by "nothing" (probably an empty string). Where do we go from here? I poked around the help files for a while trying to find mention of this behavior. There was nothing explicit but :h cmdline-lines says (scroll down a page or two) ...

When the character '%' or '#' is used where a file name is expected, they are expanded to the current and alternate file name.

I read that as Vim putting # through the expand() function (i.e. expand('#')) or at least the same underlying code used there.

:h expand() says:

Expand .. special keywords. .. When using '%' or '#', and the current or alternate file name is not defined, an empty string is used.

Sounds familiar.

The Code

Now none of the above is definitive or gives a clue as to Why? so I spent some more time digging...this time in the code. My C is very rusty and I don't have any good tools installed but I managed to find a function that does some setup for :bdelete called do_bufdel(). This sends command line arguments through buflist_findpat() which, if # is encountered, returns value curwin->w_alt_fnum. That's the "buffer number" of the alternate buffer...which can't be a positive value in our scenario. (There's no check for whether the alt file is valid/exists before that return value is selected.)

Back out in do_bufdel() a check is made against that return value for a buffer number less than 0 in which case the parameter processing loop is broken out of. That would result in no parameters being presented to the core :bdelete code...which is right in line with my earlier intuitions.

What's Next?

It appears to be working as designed in that I didn't see anything that looked like a clear bug. Possibly sin of omission, though...a corner case that has been overlooked and thus has no graceful handling. But only the developers that wrote this know for sure. So the final step would be to try to get their input. As Christian B. said asking on the vim-dev list is the way to go.

(Note that buflist_findpat() is a utility function so it wouldn't require a stretch of the imagination to assume that :bunload, :buffer, etc. are using it, too...that would explain their common behavior with respect to #.)

  • I'd think one more function for just checking if expanded buffer exists or not would do the job. Are you sure this was supposed to be by design? I think this should be listed as a bug. – klaus Jun 9 '18 at 6:55
  • I think your research is correct. BTW: I don't think this is actually a bug. – Christian Brabandt Jun 9 '18 at 8:23
  • I just reworded my conclusion a bit....it doesn't look like a hard bug. OTOH, if one thinks about it one could conclude that it needs better handling. Probably only the developer knows for sure. – B Layer Jun 9 '18 at 8:30
  • Yeah, one could ask on the vim-dev list to make sure. – Christian Brabandt Jun 9 '18 at 9:34

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.