What is NetrwBrowseX and what are the related vim mappings for? - vim

I occasionally like to map vim keys to search and then do something. I've been doing this for decades, but when I do it now, it takes over a second each time I use the mapped key.
I believe the cause is this, response from ":map" in vim:
n gx <Plug>NetrwBrowseX
n <Plug>NetrwBrowseX * :call netrw#NetrwBrowseX(expand("<cWORD>"),0)<CR>
What are these mappings for, and how can I get rid of them?
The map I'm adding today is
:map g nz.
Simply so every time I find the searched term, it's centered in the screen so I can quickly compare contexts.

Try nunmap gx.
From the source code netrw.vim:
" s:NetrwBrowseX: (implements "x") executes a special "viewer" script or program for the {{{2
" given filename; typically this means given their extension.
" 0=local, 1=remote
fun! netrw#NetrwBrowseX(fname,remote)

Related

How To Switch Between Buffers in vim by number

I'm using vim and i want to switch between buffers by number.
(e.g when i press Ctrl+2 vim should go to second buffer)
What should i write in .vimrc?
I would suggest:
" list buffers and jump to a chosen one
nnoremap <Leader>b :ls<CR>:b<Space>
The command :ls<CR> will list all opened buffers and :b[uffer]<space> allows you to type the number shown by the ls
I personally have something like this in my .vimrc:
map <F9> :bp<CR>
map <F10> :bn<CR>
As stated in the comments and :help keycodes there is no available mapping for the numbers 0-9.
I tried using map <C-k1> ... (as those are available in the keycodes), but it didn't work.
The answer depends on the approach of working with buffers.
I use the following three ways:
the buffers are showed in tabs;
the buffers are showed in windows;
the buffers can be hidden and the user switches between them using the current window.
For the first case, to switch between tabs, you may just type the buffer number and then hit the g and t keys. If it’s not suitable, make a map for the gt combination.
nnoremap <your_key_for_tab_switching> gt
For myself, I mapped the capital letters of the middle row, from “A” to “L”, for switching between tabs, but it may be not suitable for every user:
nnoremap A 1gt
nnoremap S 2gt
nnoremap D 3gt
...
nnoremap L 9gt
For switching between windows I prefer just the “next” and “prev” commands:
nnoremap <your_keys_to_the_next> <c-w>w
nnoremap <your_keys_to_the_prev> <c-w>W
To switch between opened but currently hidden buffers within a window you can:
nnoremap <your_shortcut_key> :buffer
" there is a space after “buffer”
That will be exactly you’ve asked for — “by numbers”. But it’s not a convenient way as I think. I prefer to switch between hidden buffers by short names but it’s not a standard feature.
There is yet another way — capital letters and digits for the marks. See help ma for more information.
And a little piece of advice: consider using letter-like keyboard keys instead of the number keys because they are placed much more closely to the fingers.

Setting mouse=a and mapping <esc> to :noh breaks mouse working on vim? [duplicate]

I am a happy VIM user, although I admit I'm quite far from being fluent. I found this nice post:
Vim clear last search highlighting and I thought I'd become a better person if I didn't have to hammer away a random character sequence every time I did a search. Now, I'm also using the vimrc config from here:
http://amix.dk/vim/vimrc.html
and the problem I have is that when I add the line nnoremap <esc> :noh<return><esc> to it (it doesn't seem to make a difference where I put it) I get awkward behaviour when I use arrows in command mode, namely letters from A to D appear in a newline and I get switched to insert mode.
There has to be some mapping conflict but for the life of me I can't figure out where it is.
EDIT: As it follows from the answers it turns out the Ultimate vimrc part is not relevant, the mentioned nnoremap command will cause altered arrow behaviour even if it's the only vimrc entry. Changing title to a more informative one.
PS. I know I shouldn't use arrows, hopefully I'll get there one day.
The mapping
nnoremap <esc> :noh<return><esc>
will conflict with so called "grey keys" and I believe that it should be used either in GVim only or in terminal Vim by someone who does not use special keys like arrows.
From what I know (and guess) how Vim processes keys, I would say that it's impossible to do anything with this. For Vim to recognize special key all its components should go in a row, so when you press Arrow Left Vim gets the following sequence of codes:
<esc> [ D
But after your mapping Arrow Left becomes:
: n o h l <cr> <esc>
[ D
Vim sees two separate sequences and treats <esc> as a single press of Escape key, thus next two codes of Left Arrow key lose their special meaning.
So I suggest you to map :noh to some other key sequence (e.g. to one starting with <leader>, see :help mapleader; I don't recommend you to use F-keys, using them is as bad as using of arrow keys).
The cause had been explained well, but solution was not mentioned. However there is a straight one.
If you’ll tell to Vim explicitly that there are key sequences starting from <esc>[
:nnoremap <silent><esc> :noh<CR>
:nnoremap <esc>[ <esc>[
than when single <esc> will be pressed Vim will wait for a second (or different time, see :h 'timeoutlen') or for a next key (second <esc> for example) and only then replace it with :noh<CR>.
This solution preserves the ESC mapping to :nohlsearch.
The comment on this answer explaining why this is happening tells us that the root cause is the TermResponse behavior of vim. This can be compensated for by wrapping the mapping in an autocommand for the TermResponse event.
This ensures that the binding doesn't happen until after the term response is set, which prevents Esc from also sending a string like ]>1;3201;0c to vim.
Change your line in vimrc to this:
augroup no_highlight
autocmd TermResponse * nnoremap <esc> :noh<return><esc>
augroup END
The augroup commands are not strictly necessary, but they prevent multiple mappings when you reload your vimrc without quitting vim.
EDIT: If you also use a graphical vim like Gvim or Macvim, the TermResponse event will not fire. Assuming you use a single vimrc, you'll need some additional code like
if has('gui_running')
nnoremap <silent> <esc> :nohlsearch<return><esc>
else
" code from above
augroup no_highlight
autocmd TermResponse * nnoremap <esc> :noh<return><esc>
augroup END
end
Problem is that when you press an arrow terminal emits something like <Esc>OA. Vim part that supports terminal seems to use the same mapping mechanism to do the job as you are using: while nmap <Esc>OA will tell you nothing, call feedkeys("\eOA") will move one line up and call feedkeys("\eOA", 'n') will add letter A beyond current line. With your mapping being noremappable you forbid vim to use <Esc> as a part of the key. The problem is that you need remappable mapping here, but can have remappable mapping without it being recursive as well only if it starts with {lhs}, but <Esc>:noh<CR>OA is not going to work. I thought the following code will (it uses <expr> and function with side effect to make <Esc> be the first character of the actual {rhs} and still launch :noh), but in fact it does not:
function s:NoHlSearch()
nohlsearch
return "\e"
endfunction
nmap <expr> <Esc> <SID>NoHlSearch()
. I have no other idea how to solve the problem of having non-recursive remappable mapping which includes {lhs} but not at the start.
I have had good luck with this
if $TERM =~ 'xterm'
set noek
endif
nnoremap <silent> <esc> <esc>:noh<cr>
The disadvantage is that function keys can not be used in insert mode.
:h ek

vim - Ignore timoutlen for certain key-mapping macros

I have made two simple nmaps in Vim that moves the cursor 10 times right and left by pressing Alt-z and Alt-Z
nmap <ESC>z 10l
nmap <ESC>Z 10h
It works perfect.
Now I would like to add two similar nmaps that delete 10 times
nmap d<ESC>z 10x
nmap d<ESC>Z 10X
This works almost fine, and follows the vim logic of operation followed by cursor move.
Unfortunately it times out if I don't press Altz or AltZ quickly after d.
I find this odd, because I have not mapped anything to just d. And if I press w or W after d, I can wait as long as I want.
I know there's a special thing about built-in maps such ad dw and dW.
To my question: Is there a way I can get my own nmaps to accept long delays between the key-presses?
You're right that by default, 'timeoutlen' (default 1 s) applies to mapped keys. I find this useful, but if you really want your started mappings to wait indefinitely, you have to define the map on the first key only, then query and handle the remaining keys yourself.
function! MapOrDefault()
let c = nr2char(getchar())
return c == "\<A-z>" ? '10x' : 'd' . c
endfunction
nnoremap <expr> d MapOrDefault()
Note: Though it's technically equivalent, I'd recommend to prefer the Vim key-notation (<A-z>) instead of the cryptic <Esc>z.
Note: You should use :noremap; it makes the mapping immune to remapping and recursion.

Mapping <esc> in vimrc causes bizarre arrow behaviour

I am a happy VIM user, although I admit I'm quite far from being fluent. I found this nice post:
Vim clear last search highlighting and I thought I'd become a better person if I didn't have to hammer away a random character sequence every time I did a search. Now, I'm also using the vimrc config from here:
http://amix.dk/vim/vimrc.html
and the problem I have is that when I add the line nnoremap <esc> :noh<return><esc> to it (it doesn't seem to make a difference where I put it) I get awkward behaviour when I use arrows in command mode, namely letters from A to D appear in a newline and I get switched to insert mode.
There has to be some mapping conflict but for the life of me I can't figure out where it is.
EDIT: As it follows from the answers it turns out the Ultimate vimrc part is not relevant, the mentioned nnoremap command will cause altered arrow behaviour even if it's the only vimrc entry. Changing title to a more informative one.
PS. I know I shouldn't use arrows, hopefully I'll get there one day.
The mapping
nnoremap <esc> :noh<return><esc>
will conflict with so called "grey keys" and I believe that it should be used either in GVim only or in terminal Vim by someone who does not use special keys like arrows.
From what I know (and guess) how Vim processes keys, I would say that it's impossible to do anything with this. For Vim to recognize special key all its components should go in a row, so when you press Arrow Left Vim gets the following sequence of codes:
<esc> [ D
But after your mapping Arrow Left becomes:
: n o h l <cr> <esc>
[ D
Vim sees two separate sequences and treats <esc> as a single press of Escape key, thus next two codes of Left Arrow key lose their special meaning.
So I suggest you to map :noh to some other key sequence (e.g. to one starting with <leader>, see :help mapleader; I don't recommend you to use F-keys, using them is as bad as using of arrow keys).
The cause had been explained well, but solution was not mentioned. However there is a straight one.
If you’ll tell to Vim explicitly that there are key sequences starting from <esc>[
:nnoremap <silent><esc> :noh<CR>
:nnoremap <esc>[ <esc>[
than when single <esc> will be pressed Vim will wait for a second (or different time, see :h 'timeoutlen') or for a next key (second <esc> for example) and only then replace it with :noh<CR>.
This solution preserves the ESC mapping to :nohlsearch.
The comment on this answer explaining why this is happening tells us that the root cause is the TermResponse behavior of vim. This can be compensated for by wrapping the mapping in an autocommand for the TermResponse event.
This ensures that the binding doesn't happen until after the term response is set, which prevents Esc from also sending a string like ]>1;3201;0c to vim.
Change your line in vimrc to this:
augroup no_highlight
autocmd TermResponse * nnoremap <esc> :noh<return><esc>
augroup END
The augroup commands are not strictly necessary, but they prevent multiple mappings when you reload your vimrc without quitting vim.
EDIT: If you also use a graphical vim like Gvim or Macvim, the TermResponse event will not fire. Assuming you use a single vimrc, you'll need some additional code like
if has('gui_running')
nnoremap <silent> <esc> :nohlsearch<return><esc>
else
" code from above
augroup no_highlight
autocmd TermResponse * nnoremap <esc> :noh<return><esc>
augroup END
end
Problem is that when you press an arrow terminal emits something like <Esc>OA. Vim part that supports terminal seems to use the same mapping mechanism to do the job as you are using: while nmap <Esc>OA will tell you nothing, call feedkeys("\eOA") will move one line up and call feedkeys("\eOA", 'n') will add letter A beyond current line. With your mapping being noremappable you forbid vim to use <Esc> as a part of the key. The problem is that you need remappable mapping here, but can have remappable mapping without it being recursive as well only if it starts with {lhs}, but <Esc>:noh<CR>OA is not going to work. I thought the following code will (it uses <expr> and function with side effect to make <Esc> be the first character of the actual {rhs} and still launch :noh), but in fact it does not:
function s:NoHlSearch()
nohlsearch
return "\e"
endfunction
nmap <expr> <Esc> <SID>NoHlSearch()
. I have no other idea how to solve the problem of having non-recursive remappable mapping which includes {lhs} but not at the start.
I have had good luck with this
if $TERM =~ 'xterm'
set noek
endif
nnoremap <silent> <esc> <esc>:noh<cr>
The disadvantage is that function keys can not be used in insert mode.
:h ek

Quickly switching buffers in Vim normal mode

Recently I found out that I'm "using tabs incorrectly" in Vim. I've been trying to just use buffers in Vim since, assisted through MiniBufExplorer, but I find it painful because of how many keystrokes it takes to change buffers from normal mode. With tabs, I can just do gt or gT to hop back and forth between tabs in normal mode, and I can also do NUMBERgt to go to a specific tab.
With buffers, I either have to enter command mode with :bn, :bp, or with MiniBufExplorer, use Ctrl + k or Ctrl + Up to hop up to the buffer window, scroll left or right with h and l and then hit Enter to select the buffer I want. Or I can do something involving a leader sequence, but it always requires removing multiple fingers away from home row. That's a real pain.
How can I get something equivalent switching tabs in normal mode to switch buffers in normal mode, so I can do something like gn/gp for :bn/:bp and NUMBERgn for :buf NUMBER?
Add this to your .vimrc
map gn :bnext<cr>
map gp :bprevious<cr>
map gd :bdelete<cr>
" I personally use <leader>
map <leader>n :bnext<cr>
map <leader>p :bprevious<cr>
map <leader>d :bdelete<cr>
Note that you are remapping gp and gd, but maybe you don't care about that (:help gp, :help gd).
For more information on how to map key strokes see :help map-overview and :help map.txt.
Btw, I personally use <leader> instead of g in the mapping. My <leader> is set to ;. This puts my <leader> key on the home row which makes me willing to map all kinds of stuff using <leader>. :help mapleader if you want to change your <leader> key.
The way I usually switch between buffers is to use the :buffer command with the built-in autocompletion, e.g. :b prof<Tab> to switch to folder/path/LoginProfileFactory.php.
You can just start typing any part of the file name of the buffer you need, which is nice.
Less often, I actually remember the numbers of the buffers I want and I use something like :b 3 or :3b.
I see you mention you don't like :buf 3 though, so Rumple Stiltskin has an alternative to the :3b style that you may prefer.
{count}CTRL-^ switches to the count numbered buffer.
I have the following lines in .vimrc:
nnoremap <silent> <tab> :if &modifiable && !&readonly && &modified <CR> :write<CR> :endif<CR>:bnext<CR>
nnoremap <silent> <s-tab> :if &modifiable && !&readonly && &modified <CR> :write<CR> :endif<CR>:bprevious<CR>
Now a Tab let you go to the next buffer and a Shift-Tab to the previous.
This is based on Nick Knowlson's answer, but I wanted to expand on my comment there ...
Type :b <Tab> (note the space), then cycle through the open buffers with Tab or ← / →.
... which gets us closer to the Ctrl + Tab in all the other editors and browsers I use.
It's actually even better in some ways, you can then go backwards and forwards with ← / → arrows. It avoids the thumb + finger fu to type Ctrl + Shift + Tab to go backwards through the tabs in editors and browsers.
N.B. Shift + Tab just does the same as Tab
This is then actually something like Win + Tab in Windows 10, where once you first open up the window and you can then move around using the arrow keys.
Edit: I have two further tricks that I picked up for using buffers:
From this answer I have this in my .vimrc:
nnoremap <leader>bb :buffers<cr>:b<space>
it opens the :ls / :buffers command and pre-types the :b so that you just have to type the buffer number as you'll see a list with all the buffers and their numbers.
I also have
nnoremap <leader><tab> :b#<cr>
which toggles between the current and most recently used buffers, it's a bit like doing cd - when switching back and forth between directories
I use the plugin unimpaired.vim
it defines mappings [b and ]b that jump to the previous and next buffer in the list.
For jumping for a specific buffer the best option I know is the one you mentioned: :b<number>
If you go into another buffer you can came back quickly by typing <c-^>
Expanding on Rumple Stiltskin's answer, if you know that the file you want to get to is in buffer 4, for example, you can get there quickly with
4Ctrl-^
On my UK keyboard, I can actually do 4Ctrl-6, as explained in
:help CTRL-^
By the way, you can see the buffer numbers with
:buffers
or
:ls
I use LustyExplorer: I hit <leader>b to open a list of buffers then a couple of letters from the name of the buffer I want to open then enter. Easy.
But, you are not "using tabs incorrectly", you are using tabs the way you want. If it worked for you why go through the pain of unlearning your way to learn "the right way"?
I use F9 and F10 to move between the previous/next buffer with this mapping:
map <F9> :bprevious<CR>
map <F10> :bnext<CR>
For me this is the fastest way to switch buffers.
fzf.vim is another fast way to changes buffers using fuzzy matching. This plug-in ships with the default command:
:Buffers
which opens the list of all open buffers similar to :ls but a buffer can be (fuzzy) searched and selected.
Opening the buffer in the current window is through enter, but can can also be opened in a new split (h or v) or tab using ^X ^V or ^T respectively.
Noteworthy is also:
:Lines
Which allows to search through the content of all open buffers. This can be handy if you forget the name of a buffer but you know what it should contain.
Here is my solution:
" `<leader><Tab>` - next buffer;
nnoremap <silent> <leader><Tab> :bnext<CR>
" `<leader><S-Tab>` - previous buffer;
nnoremap <silent> <leader><S-Tab> :bprevious<CR>
" `_bufferNumber_ + <Tab>` - go exact the buffer number;
nnoremap <silent> <Tab> <C-^>
By the way, I use 'buftabline' plugin and set let g:buftabline_numbers = 1 to spread my buffer on the tabline.
I make it easier for myself:
In .vimrc :
nnoremap <leader>bf :buffers<CR>:buffer "<- Last spaces is necessary
For example, in normal mode, say your leader key is \(default it is), type \bf, then you have a list of opened buffers, type number of buffer you want and hit enter key.
NOTE: remember that last spaces not necessary at all if you wich type it after :D
Jut like that ;)
More detail:
<C-O> Navigate backward
<C-I> Navigate forward
So there is no need extra remapping, otherwise you remapped them.
I think bufexplorer is a nice plugin to use. <leader>be brings up an interactive buffer explorer that lists all open buffers. You could quickly move through the list and Enter puts you in the selected buffer. Unlike LustyExplorer It has no dependency to ruby.
I prefer navigating between buffers similarly to how I'm navigating between window panes: <alt-h> and <alt-l>. This is to straightforward to set on Mac because <alt>/<option> key binds are bounded to specific characters.
" Buffer navigation
map ˙ :bp<cr>
map ¬ :bn<cr>
map § <c-^>
Here is a good answer that shows how you can see characters maped to <alt-..> combinations

Resources