Disable or remap <C-W>o single-window command in vim - vim

<C-W><C-O> or <C-W>o invoke the vim single-window command which maximizes the current vim split, and annoyingly (if you keep typing it by accident) closes all others.
I want to remap it to <C-W><C-_> which doesn't close other windows.
In .vimrc I have
map <c-w><c-o> <c-w><c-_>
map <c-w>o <c-w><c-_>
This works if I type C-W and then o or C-O in quick succession.
However, if I type C-W, then wait a second, and then type o or C-O the mappings I have set up are bypassed, and the single-window command is invoked.
Should I use some other map variation?

Another thing you can do is modify the 'timeout' and 'timeoutlen' settings:
For example :set timeoutlen=3000 will set the mapping timeout to 3 seconds instead of 1 (default).
Reference on :help 'timeout' and :help 'timeoutlen'.

The difference between mappings and the built-in two-key mappings like <C-w>o is that the former timeout, whereas the latter wait indefinitely for the second key press. To completely override the behavior with a mapping, you'd have to define an (expression-) mapping for <C-w>, and handle the second key inside the mapping with getchar() (which also waits indefinitely).
But please think carefully whether such effort is really needed: If you're prone to fat-fingering keys or pressing the wrong ones, your use of Vim will be severely hampered. Better learn through the quick feedback that you've pressed something wrong, and try to work on improving your muscle memory!

How about putting set hidden into your .vimrc, so after closing all the splits they don't get closed, only put to background? After that you can list all the opened buffers via :ls command for example.
But regards to your mapping, maybe you could try unmapping (or yet even better nunmap - which unmaps a command only in normal mode) o first, and then map it.

Related

Sometimes Vim starts ignoring mappings on Ctrl-keys

Lately, when using Vim in tmux over ssh, sometimes something happens where Vim starts ignoring all my mappings that start with Ctrl: for instance <C-P>, which I have bound to the CtrlP plugin. Instead, Vim runs the builtin action (in this case, moving lines upward in the file). I don't doubt that the correct keypress is reaching Vim, as it uses the correct builtin action associated with <C-P> (using :send-keys to send ctrl-p from tmux also causes the builtin <C-P> in vim to run, instead of the mapping).
All my mappings not involving the control key still work. For instance, I can do this:
nnoremap p :echo "test"<cr>, and pressing p echoes test
But then immediately after,
nnoremap <c-p> :echo "test"<cr>, and pressing CTRL-P doesn't echo test, it moves the cursor up one line.
Restarting Vim always fixes the issue, but at some point, something I do causes the problem to surface again. I've been working mostly in tmux through ssh lately, so I'm not 100% sure if either one of those are the problem (although I think I recall this happening once in Vim in tmux not over ssh), but as mentioned above, I believe using send-keys directly from tmux as a test is ensuring that vim is getting the actual ctrl-p keycode. As well, <C-V><C-P> in insert mode does actually insert ^P.
Note that although I've used ctrl-p here as an example, since it's a key I actually use a lot in practice, this applies to any control key mapping.
Is there some kind of Vim state I don't know about that's causing this to happen? Is this likely a terminal problem? What are my next steps?

Translucent Vim map for short manual about keys after it

In (Neo)Vim, I want to configure a key as if it passed through one-way mirror.
For example, in normal mode, when I type <Leader>, the command :echo "w: Separate Window f: Open File c: Configure Settings" run (so I can get help from at the bottom of the screen), but the <Leader> still has influence on following keys --- such as w, f, c, and so on --- and <Leader><KEY> works properly.
I mapped lots keys with <Leader>, so it will be very helpful for me to display a short manual about keys follow <Leader> at the bottom of the screen when I type <Leader>.
Thanks.
First, <leader> is not a special key at all. It's a placeholder expanded by Vim to the current value of mapleader whenever it is used. Assuming your mapleader is , (as instructed in :help mapleader), the mapping below:
nnoremap <leader>f :find *
will be registered as:
nnoremap ,f :find *
Second, when Vim detects that the key you just pressed is part of several custom or built-in commands it waits a bit for you to press more keys in order to decide what to do. With , as your mapleader, pressing , will always puzzle Vim because , is an actual command in its own right and you have a bunch of custom mappings starting with ,. In this situation, Vim waits for a full second before deciding you actually wanted , and not ,f.
Third, you would almost certainly need to write a completely separate mapping mechanism for achieving you idea. A mechanism that would:
listen to key presses,
trigger a specific function when you press <leader>,
that prints something helpful in the command-line,
and waits indefinitely for another key to be pressed.
This doesn't sound trivial at all. Did you take a look at the "scripts" section of http://www.vim.org?
Four, the whole point of a mapping is to map a common action to an easy to remember shortcut. You definitely have too many mappings if you can't remember all of them. Maybe it's time to reconsider the root issue instead of looking for a workaround?
You can do that with the following mapping:
:nnoremap <Leader> :echo "w: Separate Window f: Open File c: Configure Settings"<Bar>call feedkeys((exists('g:mapleader') ? g:mapleader : '\'), 't')<CR>
This uses feedkeys() to send the <Leader> again after the help has been shown. However, this solution has the key timeout downsides already mentioned by #romainl: The message will only appear after the 'timeoutlen' delay, and then you have to press the correct mapping key within 'timeoutlen'.
alternative
I would rather print the help on <Leader><Leader>. There are no timeout issues here. If you have pressed <Leader> and then fail to remember what's the next key, just press <Leader> again, read the help, and then start again with the (now memorized) full mapping!

Is it possible to improve this vim mapping that repeats a command on the command line?

So here is my mapping:
nnoremap <cr> :nnoremap <lt>cr> :w!<lt>cr>:!tmux send-keys -t :1.1 "py.test --cov=." C-m <lt>cr><lt>cr><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left><left>
It's pretty awesome. What it does is when I first start my vim session (or after reloading a vimrc), and hit enter, I can immediately type the name of the tmux session that I'm in and hit enter again. Assuming that I'm editing my files in the zeroth pane of window 1 and I have a tmux split (horizontal, in my typical case). Subsequent times hitting enter in normal mode will save my active file and launch my py.test tests in another window. That means that I can technically continue coding before my tests have finished passing. I forget who I first got the idea from, but h/t that guy.
Anyhow, you've no doubt noticed that there are a lot of <left>'s in that mapping, because I'd like to start the command out being able to set the session name. But there also might be cases where I'm editing my code in a different window or something, or I need to change my pytest command or something, so I still want the ability to make those modifications.
Is there a way that I can improve this mapping? Maybe by approaching it in a different way altogether?
Your initial mapping builds another mapping command, and uses <Left> to insert the cursor on the right position to complete and then execute it.
An alternative to that would be defining a custom command (e.g. :TestInSession) that takes the variable parts as argument(s). Then, your initial mapping could just build the other mapping, leaving the cursor at the end of :TestInSession, and you would have less clutter in the command-line, and easier editing at the end.
If you need the ability to re-configure your other mapping, you could define an alternative initial mapping that isn't overwritten, e.g.:
:nnoremap <Leader><cr> :nnoremap <lt>cr> ...

vim goto file in new tab-page as the default behavior

Background
Vim 7.3 all platforms.
Vim allows the user to open a file "hyperlink" by pressing gf.
Problem
Goal
Find a solution that makes gf work with tab-page as the default behavior.
Details
The current default behavior opens the new file in the same viewport, but sometimes a user might want to open the new file in a different tab using the Vim tab-page feature.
Alternatively, a user may wish to always have gf use tab-page and never open the linked file in the same viewport.
Vim allows the gf command to open in a new tab, but it requires the user to type control-W <C-W> before invoking gf.
The existing approach is not optimal, because the keystrokes are cumbersome and introduce the risk of repetitive strain injury for users who make heavy use of the gf command.
See also
Vim help:
:help gf
:help tab-page-intro
:help tab-page
:help tab-page-commands | /_gf
:help CTRL-W_gf
Desired solution
It would be desirable to do away with the need to type <C-W>gf all the time, in order to save keystrokes and reduce the risk of repetitive strain injury.
Failed attempt
The following attempt did not work (use a normal command):
:normal <C-W>gf
Questions
why does not :normal <C-W>gf work as expected?
what alternative approaches will work to make Vim exhibit the desired behavior and reach the goal?
The answer to your first question:
What comes after :normal is supposed to be raw key presses, as you'd type them in normal mode. What you used means nothing so it does nothing (you are lucky, it could mean something and fuck up your entire buffer!).
It would work if you inserted the raw representation of <C-w>:
:norm <C-v><C-w>gf
which should look like:
:norm ^wgf
The answer to your second question:
nnoremap gf <C-w>gf

In some moments vim works noticeably slowly

In some moments vim works noticeably slow. When I'm in normal mode in 100 line file, type "O" (uppercase letter o) it appears about 1-2 seconds and only then above of current line new empty line is created in insert mode (that is normal behavior). And I want to know possible reasons why this happens...
I have quite powerful computer, So the problem is not in computer.
Are you hitting <Esc> then O in very rapid succession? If so, you are seeing the delay due to certain terminal escape sequences beginning with <Esc>O. Vim has to wait to see if you are actually typing one of those sequences.
To see this for yourself, in insert mode type <Esc>OA and your cursor should move up. Pressing <Ctrl-v><Up> in insert mode will show you the escape code generated.
Type :map O
If you have a normal mapping starting with a capital O, it might be possible that Vim is waiting for a timeout to be sure that you are not starting to type a complex command.
Typically, the timeout default is of 1 second.
See :help timeout and :help timeoutlen.
If you do have a mapping starting with O, you can find where it is defined with :verbose map. You can then disable it or modify it (or remove the plugin defining the mapping).
May be you have a redefined key binding that starts with "O"... so VIM must wait to see if you are going to type the following keys

Resources