2

Launch vim without any arguments, and perform this experiment. The files a, b, c and d used in the experiment below need not exist.

  1. Execute :e a
  2. Execute :tabe b
  3. Execute :tabe c
  4. Execute :tabe d
  5. Execute :ls
  6. Press Enter to remove the output of the previous command
  7. Execute gt
  8. Execute :ls

This is the output of step 5.

:ls
  1  a   "a"                            line 0
  2  a   "b"                            line 0
  3 #a   "c"                            line 0
  4 %a   "d"                            line 1
Press ENTER or type command to continue

This shows that "c" is the alternate file (marked with #) and "d" is the current file (marked with %). So far, we see what is expected as per the documentation. If there is an existing current file, then it becomes the alternate file when we make some other file the current file.

But the output of step 8 is the following.

:ls
  1 %a   "a"                            line 1
  2  a   "b"                            line 0
  3  a   "c"                            line 0
  4  a   "d"                            line 0
Press ENTER or type command to continue

Now "a" has become the current file as expected. It is marked with %. But "d" has not become the alternate file now. The file "d" is not marked with # anymore. Why hasn't "d" become the alternate file?

Lone Learner
  • 18,088
  • 20
  • 102
  • 200
  • 1
    This is a "You shouldn't be using tabs this way". However I'm not the best person to explain this. If you did this with buffers instead it would work as expected. And honestly I don't think the alternate file should move when I change tabs. I think that might be annoying. (Especially since you don't actually change to the tab the alternate file is in when you use ``) (Also if you check each tab you will notice that each one has a different alternate file) – FDinoff Apr 23 '14 at 19:09
  • As @FDinoff stated you shouldn't be using tabs this way. Please learn to [use buffers effectively](http://stackoverflow.com/questions/21331664/how-to-show-tab-close-button-in-gvim/21338192#21338192) – Peter Rincker Apr 23 '14 at 19:37
  • @FDinoff This is not a question about how to or how not to use tabs. I don't use tabs this way. I use buffers instead. I am aware that alternate file works as expected for buffers. This question is about why it doesn't work as expected for tabs. – Lone Learner Apr 23 '14 at 20:03

3 Answers3

4

The "alternate file" is the previous file that you edited.

Until you actually switch buffers, what matters is the order of creation of buffers, not the order of access.

You edited a, then b, then c, then d:

  • a is the "alternate file" of b,
  • b is the "alternate file" of c,
  • c is the "alternate file" of d.

Because a is the first file you edited there's no "previous file" so it doesn't have an "alternate file".

Because d is the last file you edited it is not the "alternate file" of anything. It will be the "alternate file" of the next file you edit.

gt didn't make d the "alternate file" of a because you didn't edit a after d or even d after a.

Do :b a or another :tabedit a while in d and you will get d as "alternate file" of a.

As pointed out by others, what you experienced is one of the many drawbacks of using tab pages as you'd use tabs in other editors. They are fine for the problem they are designed to solve but they have millions ways to suck if you insist on treating them like file proxies.

The whole notion of "alternate file" is a navigation feature that's only applicable to buffers.

romainl
  • 186,200
  • 21
  • 280
  • 313
1

Tab pages are just containers for windows; like windows, switching between them does not change the alternate file.

Put differently: What's causing the change of the alternate file with :tabedit is the :edit part (this one introduces a different buffer, so the previous one becomes the alternate file), not the :tab part. Therefore, switching tabs (be it with :tabnext or gt) does not affect this. The same applies to window switches like <C-W>w.

The :help alternate-file provides another hint: It's in the doc/editing.txt section, which (just above) specifies:

Editing a file with Vim means:

  1. reading the file into a buffer
  2. changing the buffer with editor commands
  3. writing the buffer into a file
Ingo Karkat
  • 167,457
  • 16
  • 250
  • 324
  • The part where you say that switching tabs does not affect the alternate file doesn't seem to be true. If you perform my experiment in the question or perform some experiment of yours by switching tabs and executing the `:ls` command after every such switch, you'll find that the alternate file does change after every switch. – Lone Learner Apr 23 '14 at 20:07
  • No, each window has its own alternate file. When you switch windows / tabs, you also get its different alternate file. Think about it - this behavior makes a lot of sense. – Ingo Karkat Apr 23 '14 at 20:42
  • In that case, in step 5, why do we see "c" as the alternate file when we are at the window for "d" in the last tab page? We never switched buffers in the window in the last tab page, so there should have been no alternate buffer for the window in the last tab page. But there is. – Lone Learner Apr 23 '14 at 20:45
  • Well, window splits (and tab pages count there, too) "inherit" certain things from the original. – Ingo Karkat Apr 23 '14 at 20:47
  • Could you please be more specific? What exactly is inherited from the original? What causes the window in the last tab page to have an alternate buffer but the window in the first tab page not to have an alternate buffer? – Lone Learner Apr 23 '14 at 20:49
  • Also, I am unable to prove how each window has its own alternate file. Open vim. Then execute `:e a`, `:sp b`, `:sp c`, `:sp d`. Then press `Ctrl-w W` to return to the first window containing "a". Now `:ls` would show "a" as the current file while "b" as the alternate file even though we haven't switched buffers in the first window. – Lone Learner Apr 23 '14 at 20:52
0

This is because every window keeps is own alternate file. Since you haven't switched buffers yet in the first window, you don't have an alternate file for that particular window.

Christian Brabandt
  • 8,038
  • 1
  • 28
  • 32
  • I tried verifying what you have said using split windows and unfortunately I don't find your explanation to be correct. Open vim. Then execute `:e a`, `:sp b`, `:sp c`, `:sp d`. Then press `Ctrl-w W` to return to the first window containing "a". Now `:ls` would show "a" as the current file while "b" as the alternate file even though we haven't switched buffers in the first window. – Lone Learner Apr 23 '14 at 20:34
  • Also, if you see my experiment in the question, when you are in the last window (in the tab page for d), alternate file is set (see output of step 5) even though we never switched buffers in that tab page. – Lone Learner Apr 23 '14 at 20:35
  • That is because in the split case, Vim internally sets the altenate buffer for the old window. – Christian Brabandt Apr 23 '14 at 20:50
  • In the tabedit case, the new window in the new tabpage will inherit the alternate file from the previous window. – Christian Brabandt Apr 23 '14 at 20:55
  • Yes, please point me to it. Which file of the source code do I need to look at? – Lone Learner Apr 23 '14 at 20:57
  • The header file structs.h – Christian Brabandt Apr 23 '14 at 20:58