Plugins breaking vim mappings? - vim

I just installed DelimitMate and CloseTag plugins for MacVim and they seem to have broken these two mapping in my .vimrc:
"F7 WordProcessorOn
:map <leader>w :set linebreak <CR> :set display+=lastline <CR> :set wrap <CR> :setlocal spell spelllang=en_gb <CR>
"F8 WordProcessorOff
:map <leader>c :set nowrap <CR> :set nospell <CR>
Does anyone have any ideas as to what the problem could be? Thanks.

You can find out what is 'hijacking' the mappings by doing
:verbose map <leader>c
:verbose map <F8>
etc.
But likely your problem is with submappings firing: use
:noremap <leader>c .......
to prevent remapping
PS: consider mapping for specific modes (nnoremap over noremap); Being explicit avoids funny interfering mappings a lot of the time

Related

How to do Vim mapping on help page only

I would like to go-to a tag when pressing enter (instead of clicking with the mouse when mouse=a) or pressing ctrl-], which is a bit of a stretch for me. Is it possible to do the mapping in the help section only, such as:
:nnoremap *help* <CR> <C-]>
I do exactly that in an ftplugin for :help files: put your mapping in ~/.vim/after/ftplugin/help.vim and use <buffer>:
nnoremap <buffer> <CR> <C-]>
Create a buffer-local mapping when a help file is loaded:
:autocmd BufReadPost $VIMRUNTIME/doc/help*.txt nnoremap <buffer> <CR> <C-]>
If the "help page" you meant is vim doc/help, they have ft=help. You can verify it by :echo &ft or :set ft?.
Then it is easy if you want to create mapping only for those filetypes. You can do it using autocommand:
autocmd FileType help map....
If you want it to be buffer local mapping, you add <buffer> in mapping.

How do I debug a non-functioning keymap in Vim?

I ask this question generally, but I will put it in terms of the specific problem I'm having.
I'm using the vim-lawrencium plugin for a project under Mercurial source control. I use the :Hgstatus command to open the status buffer.
The status buffer comes with some nice keymaps to make it easy to add files to the commit, look at diffs, and finalize the commit.
nnoremap <buffer> <silent> <cr> :Hgstatusedit<cr>
nnoremap <buffer> <silent> <C-N> :call search('^[MARC\!\?I ]\s.', 'We')<cr>
nnoremap <buffer> <silent> <C-P> :call search('^[MARC\!\?I ]\s.', 'Wbe')<cr>
nnoremap <buffer> <silent> <C-D> :Hgstatustabdiff<cr>
nnoremap <buffer> <silent> <C-V> :Hgstatusvdiff<cr>
nnoremap <buffer> <silent> <C-U> :Hgstatusdiffsum<cr>
nnoremap <buffer> <silent> <C-H> :Hgstatusvdiffsum<cr>
nnoremap <buffer> <silent> <C-A> :Hgstatusaddremove<cr>
nnoremap <buffer> <silent> <C-S> :Hgstatuscommit<cr>
nnoremap <buffer> <silent> <C-R> :Hgstatusrefresh<cr>
nnoremap <buffer> <silent> q :bdelete!<cr>
Most of these seem to work. I've successfully tried diffing, adding, and q to close the status, but the <C-S> shortcut doesn't work at all. I can manually run the :Hgstatuscommit command it's mapped to. I've also looked at :map to verify the key is actually mapped for that buffer, and it does show up in the list.
What is my next step in debugging this? I want to fix this specific problem, but I also want to know how to fix it in the event I run across broken shortcuts in the future. I'm new to Vim, so I'm at a bit of a loss at this point.
UPDATE: Output of :verbose map <C-S>
v <C-S> *#:Hgstatuscommit<CR>
Last set from ~/.spf13-vim-3/.vim/bundle/vim-lawrencium/plugin/lawrencium.vim
n <C-S> *#:Hgstatuscommit<CR>
Last set from ~/.spf13-vim-3/.vim/bundle/vim-lawrencium/plugin/lawrencium.vim
SOLUTION: Turned out the problem was that my shell was intercepting Ctrl-S and it was never getting to Vim.
I added a Vim alias to my .zshrc to fix:
alias vim="stty stop '' -ixoff ; vim"
ttyctl -f
Found the fix on the Vim Wikia which also has a solution for bash shells.
Software Flow Control
If you are using using a terminal then it is often the case that <c-s> is being used for terminal's software flow control (XON/XOFF). Which makes <c-s> a trickier key to map.
Turn off flow control by adding the following to some startup script (e.g. ~/.bash_profile or ~/.bashrc):
stty -ixon
If you have frozen your terminal then you can unfreeze it by pressing <c-q>.
Generic map debuging
You can debug pretty much any custom vim mapping via the following command:
:verbose map
This will list out each key/chord ({lhs}) maps to what command ({rhs}), mode, and file the mapping was sourced from. For more information on this listing see :h map-listing and :h :map-verbose.
We can filter this list in a few ways:
Supplying a mode. e.g. :verbose nmap for normal mode and :verbose imap for insert mode.
Proving the key we want to query for. e.g :verbose nmap <c-s>
Can also see buffer specific mappings by adding <buffer>. e.g. :verbose nmap <buffer> <c-s>
So for your question the best way to debug what your mapping is set to would be to run the following query:
:verbose nmap <buffer> <c-s>
Note: Vim's native command are not listed via :verbose map. The best way to find one of Vim's native commands is to help. See :h for more.
First, check that <C-S> still mapped to :Hgstatuscommit
map <C-S>
Hgstatuscommit calls s:HgStatus_Commit. Open its definition on line 1134 and put some debugging print outs:
echom a:linestart
echom a:lineend
echom a:bang
echom a:vertical
After using the mapping, check :messages.
I’d suspect that <C-S> is mapped to something else. You can use :map
<C-S> to check how (or if) its mapping is configured. Even better, you can
add the prefix to see where the mapping was set from, e.g., when I run
:verbose map <C-L>, the following is displayed:
<C-L> * :noh<CR><C-L>
Last set from ~/.vimrc
By contrast, I haven’t set a mapping for <C-S> so when I run, :map <C-S>,
I get:
No mapping found
Prepending verbose to a command is a useful general debugging technique as it can show where any Vim option was set, e.g., :verbose set background? shows what the background option is currently set to and which Vim configuration file it was set in:
background=dark
Last set from ~/.vimrc

Prevent certain command mappings while in NERDTree window in Vim

I have the following keys mapped in my .vimrc file:
noremap <silent> <C-h> :bprev<CR>
noremap <silent> <C-l> :bnext<CR>
The commands they execute are provided from the buftabs script.
What I would like to do is prevent those key mappings from being executed when I'm in the NERDTree split. The reason for this is if the commands are run while in NERDTree, a file buffer gets loaded in the split instead. Then, to fix it, the window needs to be closed and opened again.
This is a similar problem as explained in another question, but the problem there was corrected by configuring the plugin, while the buftabs script does not have such an option.
In order to disable a mapping in certain buffers, one can define
a buffer-local mapping for the same key sequence, overriding the
original mapping with a no-op:
:autocmd FileType nerdtree noremap <buffer> <c-h> <nop>
:autocmd FileType nerdtree noremap <buffer> <c-l> <nop>
(See :help :map-arguments and :help <nop> for details on
<buffer> and <nop>, respectively.)
I updated my vimrc by looking at ib.'s solution.
autocmd FileType nerdtree noremap <buffer> <A-PageDown> <ESC>:wincmd w <bar> bnext<CR>
autocmd FileType nerdtree noremap <buffer> <A-PageUp> <ESC>:wincmd w <bar> bprevious<CR>
It goes back to the previous window and executes the command.

How do I map ctrl x ctrl o to ctrl space in terminal vim?

After searching a bit on the net it seems that I can't map CtrlSpace to anything/alot. Is there a way to do it today, what I found was usually 2 years old.
I've run into the same issue, the short answer is yes you can, and not only in the gui version. Adding this on you .vimrc is enough:
inoremap <C-Space> <C-x><C-o>
inoremap <C-#> <C-Space>
The problem seems to be that Terminal.app doesn't interpret <C-Space> correctly and Vim understands it as <C-#> which is a built-in mapping (:help CTRL-#).
Maybe you could go with something like the following in your .vimrc:
if !has("gui_running")
inoremap <C-#> <C-x><C-o>
endif
which seems to work, here, but I don't like the idea of overriding built-ins like that.
Instead you should try with <Leader> (:help leader), it gives you huge possibilities for defining your own custom mappings and (depending on the mapleader you choose) won't interfere with OS/app specific shortcuts/limitations and hence be more portable.
With this in my .vimrc:
let mapleader=","
inoremap <leader>, <C-x><C-o>
I just hit ,, to complete method names.
The nitpicker broke pablox solution. The crux of the solution was just about remapping. So when you disable remapping, it cannot work.
If you really want to throw in a noremap, this is what it looks like:
inoremap <expr><C-space> neocomplete#start_manual_complete()
imap <C-#> <C-Space>
What will not work: inoremap <C-#> <C-Space> 'cause the <C-Space> part will not be remapped itself.
Have you tried :inoremap <c-space> <c-x><c-o> ?
Does CtrlX CtrlO do anything when you type in insert mode? Is omnifunc set?
Add the following code to ~/.vimrc:
" Ctrl-Space for completions. Heck Yeah!
inoremap <expr> <C-Space> pumvisible() \|\| &omnifunc == '' ?
\ "\<lt>C-n>" :
\ "\<lt>C-x>\<lt>C-o><c-r>=pumvisible() ?" .
\ "\"\\<lt>c-n>\\<lt>c-p>\\<lt>c-n>\" :" .
\ "\" \\<lt>bs>\\<lt>C-n>\"\<CR>"
imap <C-#> <C-Space>
Source: https://coderwall.com/p/cl6cpq
To accommodate both Windows and Linux I applied this to ~/.vimrc
if has("unix")
inoremap <C-#> <c-x><c-o>
elseif has("win32")
inoremap <C-Space> <c-x><c-o>
endif
I had better results with this set of mappings across all modes on Mac OS. Have not tested Windows or Linux.
I don't understand how the excepted answer is supposed to work in terminal mode.
inoremap <C-space> <ESC>
vnoremap <C-space> <ESC>
cnoremap <C-space> <C-c>
" When in terminal, <C-Space> gets interpreted as <C-#>
imap <C-#> <C-space>
vmap <C-#> <C-space>
cmap <C-#> <C-space>
Like the others said, using inoremap with the correct key for your term (as discovered using i_Ctrl_v) should work. I will add to this another possible cause for problems with insert mode mappings: paste mode. As the docs state:
When the 'paste' option is switched on (also when it was already on):
- mapping in Insert mode and Command-line mode is disabled
This may seem irrelevant, but this very thing tripped me up trying to get a similar inoremap binding to work in Vim 8.2. I had set paste in my .vimrc, and had to chop it up with :finish statements (as [recommended in the vim faq) to isolate the line causing the problem.

Vim: remap key to toggle line numbering

I added:
set number
nnoremap <F2> :set nonumber!
to my vimrc file. Basically what it's supposed to do is let me press F2 to toggle line numbering but it's not working. What have I done wrong?
In your .vimrc, add this:
set number
nnoremap <F2> :set nonumber!<CR>
Then pressing F2 will toggle line numbering.
This is what I use (with a different key binding):
nmap <f2> :set number! number?<cr>
The "number!" toggles the setting and "number?" reports the state.
nmap <silent> <F11> :exec &nu==&rnu? "se nu!" : "se rnu!"<CR>
In new vim you can set both relative number and number at once, this way:
set nu rnu
This is one method:
map <silent> <F2> :if &number <Bar>
\set nonumber <Bar>
\else <Bar>
\set number <Bar>
\endif<cr>
(this one is nice 'cause I usually put foldcolumn in there as well)
This is another:
map <silent> <F2> :set invnumber<cr>
(direct method)
I use this to toggle between relativenumber ( with current absolute line number) and no line numbering
nnoremap <silent> <leader>l :set relativenumber! <bar> set nu!<CR>

Resources