How to unmap vim shortcuts upon quickfix exits - vim

Background: I'm using skwp's dotfiles, and his recently changes is breaking some functionalities I use on daily basis.
Instead of set up the mappings globally, I'm trying to nnoremap two shortcuts upon quickfix enters and nunmap after quickfixes quits.
BTW, I think syntastic is used for linting, which invokes the quickfix/location lists.
Here's the code:
augroup quickfixShortcutsGroup
autocmd!
autocmd BufWrite * :echom "Foo"
" au BufReadPost quickfix nnoremap <silent> <C-z> :cp<CR>
" au BufReadPost quickfix nnoremap <silent> <C-x> :cn<CR>
au BufWinEnter quickfix nnoremap <silent> <C-z> :cp<CR>
au BufWinEnter quickfix :echo '1'
au BufWinLeave quickfix nnoremap <silent> <C-z> :cp<CR>
au BufWinLeave quickfix :echo 'BufWinLeave'
au BufLeave qf :echo 'BufLeave'
au BufUnload qf :echo 'unload qf'
" au BufLeave qf noremap <silent> <C-z> :cb<CR>
" au BufLeave quickfix noremap <silent> <C-z> :cb<CR>
" au BufWinLeave quickfix noremap <silent> <C-z> :cb<CR>
" au BufWinLeave quickfix nunmap <C-z>
" au BufWinLeave quickfix :echom 'Hello'<cr>
" BufWinEnter
augroup END
After read reference:
http://vimdoc.sourceforge.net/htmldoc/autocmd.html#BufWinLeave
http://vimdoc.sourceforge.net/htmldoc/autocmd.html#autocmd-patterns
I still could not get unmap events working, i.e. BufWinLeave, BufUnload, BufLeave are not invoked.
Can Vimers tell me which event(s) I should be using and help me out on this? Thank you in advance for the help.

As :help BufWinLeave explains, the current buffer "%" may be different from the buffer being unloaded "". So you need a global autocmd, and resolve the buffer number that has been left, and then check for the quickfix 'buftype':
autocmd! BufWinLeave * if getbufvar(bufnr(expand('<afile>')), '&buftype') ==# 'quickfix' | echo "leaving quickfix" | endif
But in general, I'd advise against such tricks and especially conditional mappings. Your <C-z> / <C-x> mappings are still global, now just depending on whether the quickfix list is visible. That's bad for muscle memory, and the overload of the key combos is mentally taxing. I'd rather get rid of the mappings completely, or assign different (if potentially longer) keys.
And there's the next complication: Vim "distributions" and other people's dotfiles lure you with a quick install and out-of-the-box settings, but you pay the price with increased complexity (you need to understand both Vim's runtime loading scheme and the arbitrary conventions of the distribution) and inflexibility (the distribution may make some things easier, but other things very difficult). Vim is incredibly customizable, using someone else's customization makes no sense.

If you would like to nnoremap these two mappings upon quickfix enters and nunmap after quickfix quits, you could
" map silently upon entering Quickfix
autocmd BufWinEnter * if &buftype == 'quickfix'
\| nnoremap <silent> <C-x> :cn<CR>
\| nnoremap <silent> <C-z> :cp<CR>
\| endif
" unmap upon leaving Quickfix
autocmd BufWinLeave * if &buftype == 'quickfix'
\| nunmap <C-x>
\| nunmap <C-z>
\| endif
Or you can make use of local buffer mapping to make your code shorter
" map silently upon entering Quickfix, and only for Quickfix
autocmd BufWinEnter * if &buftype == 'quickfix'
\| nnoremap <buffer><silent> <C-x> :cn<CR>
\| nnoremap <buffer><silent> <C-z> :cp<CR>
\| endif
These autocmd's are invoked every time you enter or leave a buffer. So it is really better just, as Sato Katsura suggested, add in your ~/.vim/ftplugin/qf.vim
nnoremap <buffer><silent> <C-x> :cn<CR>
nnoremap <buffer><silent> <C-z> :cp<CR>
You may consider to read these:
:h ftplugins
:h map-local
:h buftype
:h line-continuation

Related

Why can I combine `Plug` and `set` in vimrc, but cannot `nnoremap`?

I can combine two lines like below,
autocmd VimEnter * PlugInstall --sync | source $MYVIMRC
Plug 'sheerun/vim-polyglot' | Plug 'ap/vim-css-color'
set splitright splitbelow
but cannot with nnoremap like below.
nnoremap <Up> gk | nnoremap <Down> gj
Why this happens, and how could I resolve?
solved.
need to trim white space before |.

Making commands work only for chosen filetype(s)

I want to map F2 to compiling tex files, and F3 for viewing tex files.
This is what I put in my .vimrc:
if &filetype == "tex"
nnoremap <F2> :Latexmk<cr>
inoremap <F2> <Esc>:Latexmk<cr>a
nnoremap <F3> :LatexView<cr>
inoremap <F3> <Esc>:LatexView<cr>a
endif
These Latex* commands are from LaTeX-Box plugin. I can execute them manually without any problems. Typing :echo &filetype in any *.tex file returns tex.
You have two methods…
Create a self-clearing group in your vimrc and add as many autocommands as needed:
augroup Tex
autocmd!
autocmd FileType tex nnoremap <buffer> <F2> :Latexmk<cr>
autocmd FileType tex nnoremap <buffer> <F3> :LatexView<cr>
autocmd FileType tex inoremap <buffer> <F2> <Esc>:Latexmk<cr>a
autocmd FileType tex inoremap <buffer> <F3> <Esc>:LatexView<cr>a
augroup END
Use a ftplugin:
Put the following in after/ftplugin/tex.vim:
nnoremap <buffer> <F2> :Latexmk<cr>
nnoremap <buffer> <F3> :LatexView<cr>
inoremap <buffer> <F2> <Esc>:Latexmk<cr>a
inoremap <buffer> <F3> <Esc>:LatexView<cr>a
The second method is recommended because it is a lot cleaner and less expensive than the first.
I replaced the code above with this:
autocmd FileType tex nnoremap <buffer> <F2> :Latexmk<cr>
autocmd FileType tex nnoremap <buffer> <F3> :LatexView<cr>
autocmd FileType tex inoremap <buffer> <F2> <Esc>:Latexmk<cr>a
autocmd FileType tex inoremap <buffer> <F3> <Esc>:LatexView<cr>a

remove netrw s-up and s-down mapping in vim

I have the following mappings in my .vimrc file that I use to move between windows, but when in an explore window :e of netrw plugin the shift down key will produce a warning window instead of respecting my mappings. I am assuming this mapping must be hard coded into the plugin itself. How can I remove the shift-up and shift-up mappings in the plugin.
nnoremap <silent> <S-Up> :wincmd k<CR>
nnoremap <silent> <S-Down> :wincmd j<CR>
The window that shows up when trying to do a shift-up or shift-down is below, which shows up in a new split which is very annoying:
**warning** (netrw) using Nexplore or <s-down> improperly; see help for netrw-starstar
As a result, my question is how can I shut off this behavior in the netrw plugin so that it respects my mappings shown above instead.
A buffer map for that is created by the plugin, so you could overwrite it again after created with an autocmd:
autocmd filetype netrw nnoremap <buffer> <s-down> :wincmd j<cr>
If using multiple times, it might be useful to create a group:
augroup netrw_maps
autocmd!
autocmd filetype netrw call ApplyNetrwMaps()
augroup END
function ApplyNetrwMaps()
nnoremap <buffer> <s-up> :wincmd k<cr>
nnoremap <buffer> <s-down> :wincmd j<cr>
" ...
endfunction

Clear search highlight on autocmd BufWrite

I tried most of the suggestions in those three questions:
Get rid of Vim's highlight after searching text
How to get rid of search highlight in Vim
Vim clear last search highlighting
It's mainly the :noh, and it works when I type it manually. I just want it happen on BufWrite, so I tried multiple ways, none of which worked:
function! RemoveHighLight()
:noh
endfunction
autocmd BufWrite * :call RemoveHighLight()
autocmd BufWrite * :noh
autocmd BufWrite * :execute "normal! :noh\<cr>"
Debuging echoms and adebug\<esc> in the function and in the third autocmd show that they execute successfully, just the :noh has no effect.
(Also tried :let #/ = "" which worked but it clears the search pattern, which is not I'm looking for. I just want to get rid of the highlight til pressing n or similar)
Using BufWritePost doesn't have effect, either.
It is a workaround but you can set nohlsearch by autocmd. Then you can add a mapping to set it back by n and N.
au BufWrite * set nohlsearch
nnoremap <silent> n n:set hlsearch<CR>
nnoremap <silent> N N:set hlsearch<CR>
Or maybe better, check if it is already set
au BufWrite * set nohlsearch
nnoremap <silent> n n:call ToggleHlBack()<CR>
nnoremap <silent> N N:call ToggleHlBack()<CR>
function! ToggleHlBack()
if &hlsearch == 'nohlsearch'
set hlsearch
endif
endfunction

How to set the cursor focus after toggling the NERDTree in vim?

By default I have turned off the NERDTree and I use F2 to toggle it.
" autocmd VimEnter * NERDTree
" autocmd VimEnter * wincmd p
nmap <silent> <special> <F2> :NERDTreeToggle<RETURN>
After turning on the NERDTree by pressing F2, the cursor is then focused on the NERDTree window. My question is how to redesign the F2 shortcut so the focus window NOT to the NERDTree window?
This should do it:
nnoremap <silent> <special> <F2> :NERDTreeToggle <Bar> if &filetype ==# 'nerdtree' <Bar> wincmd p <Bar> endif<CR>
After toggling, it checks whether it now is in the NERDTree buffer. If it is, it jumps back to the previous window.
PS: You should use :noremap; it makes the mapping immune to remapping and recursion.

Resources