3

I have done a bit of research about this but found only very old answers, like this one, and all on the negative side.

My problem is the following --- suppose you are working on a document/program, say for example a LaTeX file. You have some error and you open another window/tab with the log file, which is opened in read-only mode (the same for the quickfix window).

Then you switch to insert mode in your main file, and all the windows/tabs/buffers enters insert mode. So I can't switch rapidly to the "log" windows/tab to scroll/move/hitting "q" to close it, because it's in input mode...

example, log file in input mode

So the question is — is it possible to remember the mode at a window/tab level?

I understand that it could have been confusing in the original vi, but with things like airline and colors it's quite handy to know the mode in which you are...

  • 6
    If you get used to staying in normal mode, you won't have such problems ... and the Vim "way" is normal mode. – VanLaser Feb 13 '16 at 11:48
  • @VanLaser yep, probably you're right. Will try to see if I can switch to normal mode every time I switch tab/window... – Rmano Feb 13 '16 at 12:00
  • 2
    If you switch windows using Vim's maps that start with Ctrl-w, you have to be in normal mode anyway ... – VanLaser Feb 13 '16 at 12:07
  • 1
    How do you switch windows in the first place? With the mouse? I don't really understand how you get this problem in the first place... – Karl Yngve Lervåg Feb 13 '16 at 12:48
  • 1
    @KarlYngveLervåg yes, I admit with shame --- with the mouse... – Rmano Feb 13 '16 at 14:15
4

In order for Vim to remember if you are in insert mode or not for each window opened, you could add the following autocmds inside your vimrc:

augroup RememberMode
    autocmd!
    autocmd WinLeave * let w:mode_state = mode()
    autocmd WinEnter *
                \ if exists('w:mode_state') && w:mode_state ==# 'i' |
                \     startinsert |
                \ elseif exists('w:mode_state') && mode() ==# 'i' |
                \     stopinsert |
                \ endif
augroup END

The first one autocmd WinLeave * let w:mode_state = mode() stores the mode in which you are when you leave a window (WinLeave event) inside the window-local variable w:mode_state (you can change the name of the variable if you don't like it, but keep the window-local scope w:).

The second one tests, when you enter a window (WinEnter event), whether the window-local variable w:mode_state exists (because if it's a window you just created, it will not exist and the following test would probably raise an error), and if its value is 'i'.
If it is, it means that the last time you left this window you were in insert mode, so Vim puts you back in insert mode with the Ex command :startinsert.

Otherwise, the autocmd tests whether w:mode_state exists and you're in insert mode. In this case, it means that you were already in this window in the past (otherwise the variable wouldn't exist), but you were not in insert mode (because this case has already been covered), you were in another mode. So Vim makes you quit insert mode with the Ex command :stopinsert.


For more information, see:

:help :augroup
:help :autocmd
:help WinLeave
:help WinEnter
:help w:
:help mode()
:help exists()
:help :startinsert
:help :stopinsert
3

I'm going to be bold and claim that your problem will be solved if you learn to use Vim/vi without using the mouse. Learn to stay in normal mode on a default basis, from which changing the window can be done with <c-w><c-w>. You will be happier in the long term, even though this may take some effort and time in the short term.

Note: I know this is not an answer to your actual question, and I'll accept being downvoted for that reason.

  • 1
    No reason to downvote. It's a completely reasonable answer. I'll try.... – Rmano Feb 13 '16 at 22:49

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.