Vim: don't remap keys in history or help buffers - vim

I have added this to my .vimrc in order to append a newline without leaving Normal mode:
nmap <Enter> o<Esc>
The problem is when I q: to the command history buffer. This binding clashes with the usage of Enter for selecting a command from history. A lesser problem is when reading a help page hitting Enter will display a warning that the file is read-only. How can I remap this key in a way that ignores these two contexts?

You can undo the global mapping for the command-line window via a buffer-local mapping to itself:
autocmd CmdwinEnter * nnoremap <buffer> <Enter> <Enter>
(My ingo-library plugin provides a generic ingo#window#cmdwin#UndefineMappingForCmdwin() function for that.)
For the help buffer, use the same approach, but trigger on the FileType event:
autocmd FileType help nnoremap <buffer> <Enter> <Enter>

You can set it with autocmd using this method https://stackoverflow.com/a/10410590/3627387
let blacklist = ['nofile', 'help']
autocmd FileType * if index(blacklist, &bt) < 0 | nmap <Enter> o<Esc>
Here we are checking for buffer type :help 'buftype'

Related

Use <Esc> key to save file with one key press in Insert mode or Normal mode

I try to map my <Esc> key to save file with one key press only.
In Normal Mode, it works so far.
map <Esc> :w <CR>
But I have trouble to map it in Insert mode,
I tried the following command, but it does't work
map <Esc> <Esc>[ :w <CR>
By the way, I only want One Key Press only.
Please give me some suggestions, or if you know any good key to save file with One press in Vim
Note that mapping <Esc>, especially in insert mode, is not recommended. Most special keys (like cursor and function keys) are sent as Escape sequences by the terminal. An alternative would be hooking into the InsertLeave event:
:autocmd InsertLeave * silent! update
:update is better suited than :write, because it only actually saves when there are unpersisted updates. :silent! suppresses errors when the buffer hasn't been named, etc.
You keep emphasizing One press as if it was the most important part of your problem but the important part is Insert mode.
:map is a recursive mapping command for normal, visual and operator-pending modes.
You are supposed to use :imap — or its non-recursive friend :inoremap — for insert mode:
:inoremap <Esc> <Esc>:w<CR>
For what it's worth, I recommend Ingo's solution.
augroup AUTOSAVE
au!
autocmd InsertLeave,TextChanged,FocusLost * silent! update
augroup END
To autosave on InsertLeave, TextChanged and FocusLost events

Toggle show list of buffers in vim

There is this cool tip in Vim wikia to work with buffers:
nnoremap <F5> :buffers<CR>:buffer<Space>
How can I turn it into a toggle? That is, first press of <F5> shows the list of buffers, press it again, and it closes the list of buffers (for me it's more intuitive than pressing ESC) Also, I would like to do the same for :Hex with, say <F2>, that is, press <F2>, opens file explorer in a split, repress <F2>, closes file explorer.
I do not know what you mean by toggling buffer list. You can dismiss the command line via <esc>. I guess you could do cnoremap <f5> <esc>. This works because pressing <f5> in normal mode brings up the buffer list and keeps you in command-line mode. You map <f5> in command-line mode to <esc> to dismiss the prompt.
:Hex opens a split an netrw explorer buffer. You can simply close the buffer any number of ways: <c-w>c, :q, :close, and so on. To make an <f2> mapping that closes a netrw buffer you can add the following to you ~/.vimrc file:
augroup ToggleNetrw
autocmd!
autocmd FileType netrw nnoremap <buffer> <f2> :<c-u>close<cr>
augroup END
Your <f2> mapping does :Hex and we map a buffer specific <f2> mapping for netrw filetypes to close the buffer via :close.
:Lexplore will toggle the explorer in the current buffer's directory.
You can map to something like:
nnoremap <F2> :Lex<CR>
alternatively you can give a size for the opening netrw:
nnoremap <F2> :20Lex<CR>
In the above example, 20 is the percentage drawn from the current buffer size.
More information can be found by the vim command: :h Lexplore among other resources.
------- EDIT about toggling buffer list.
You can toggle the buffer list after executing the mapping you have by pressing the tab key, if that's what you mean.

How do I map keys for specific file types in Vim?

I want my Enter key to follow links in help files because my keyboard doesn't have a ] key. Therefore I've put:
nnoremap <Enter> <C-]>
In ftplugin/help.vim. This works, but this key map is now "global" and messes up the use of the key in other places, for example the q: command window.
So how do I restrict a key-bind to a single buffer, or perhaps even a single file type?
map the command using autocmd:
autocmd FileType c,cpp,php nnoremap <buffer> <Enter> <C-]>
maps only for filetypes: c,cpp and php
Just add <buffer> to your mapping:
nnoremap <buffer> <Enter> <C-]>

How to always clear hlsearch on clicking enter?

Right now I am using:
nnoremap <cr> :nohlsearch<cr><cr>k
But after I press Enter my cursor goes to beginning of line.
I have additional <cr>k because I want to use default <Enter> behaviour for example when I try to open file in Ack results quickview.
If you want Enter to keep the default behavior, then this mapping should take care of it.
nnoremap <CR> :nohlsearch<CR><CR>
It turns off search highlighting, moves the cursor down, and only applies to normal mode.
An alternative approach is to locally override the new behavior in the quickfix window and the command-line window, where <CR> has special meaning:
:nnoremap <CR> :nohlsearch<CR>
:autocmd BufReadPost quickfix nnoremap <buffer> <CR> <CR>
:autocmd CmdwinEnter * nnoremap <buffer> <CR> <CR>

How to map keys in vim differently for different kinds of buffers

The problem i am facing is that i have mapped some keys and mouse events for seraching in vim while editing a file. But those mappings impact the functionality if the quickfix buffer.
I was wondering if it is possible to map keys depending on the buffer in which they are used.
EDIT - I am adding more info for this question
Let us consider a scenario. I want to map <C-F4> to close a buffer/window. Now this behavior could depend on a number of things.
If i am editing a buffer it should just close that buffer without changing the layout of the windows. I am using buffkil plugin for this.
It does not depend on extension of file but on the type of buffer. I saw in vim documentation that there are unlisted and listed buffer. So if it is listed buffer it should close using bufkill commands.
If it is not a listed buffer it should use <c-w>c command to close buffer and changing the window layout.
I am new at writing vim functions/scripts, can someone help me getting started on this
function KillBuffer()
if &buflisted
" bufkill command here
else
execute "normal! \<C-w>c"
endif
endfunction
noremap <C-F4> :call KillBuffer()<CR>
Put this in your .vimrc
Or, if you want to handle quickfix window as unlisted buffers (in my Vim it is listed):
function KillBuffer()
if &buflisted && !&filetype=="qf"
" bufkill command here
else
execute "normal! \<C-w>c"
endif
endfunction
noremap <C-F4> :call KillBuffer()<CR>
According to the manual, you could replace execute "normal! \<C-w>c" with simpler close! in the above scripts.
You can create filetype specific settings. First, in your vimrc file, make sure filetype plugins are enabled by adding
filet plugin on
Then make a filetype specific plugin. Under Unix create a file called ~/.vim/after/ftplugin/[file-type-name].vim and put your mapping in there. In Windows the directory is $HOME/vimfiles/after/ftplugin. The [file-type-name] is the type detected by Vim, sometimes the same as the filename extension, e.g c.vim, python.vim, etc. Vim can tell you what the type is after you open the file if you enter
:echo &ft
You can intercept certain types of files loading and assign buffer specific mappings.
au! BufRead *.ext call <SID>init_hotkeys()
function s:init_hotkeys()
nnoremap <buffer> <CR> :Action<CR>
endfunction
To map complex logic on the hotkey you can use write something like this in your vimrc, or even better - put the following to the closebuffer.vim file inside your vim plugin directory
function s:close_buffer()
if &buflisted
" your command here from the killbuf plugin
echo "Listed Buffer"
else
wincmd c
" or
" normal <c-w>c
endif
endfunction
nnoremap <C-F4> :call <SID>close_buffer()<CR>
I use this in my vimrc to insert an empty line above or below the current line using only return and shift-return (as opposed to o<Esc> or O<Esc>) without interfering with the open file behaviour you want in the quickfix list.
" Use enter to insert newlines in normal mode, but not in quickfix
function! s:insert_line(direction)
if &buftype == "quickfix"
execute "normal! \<Enter>"
else
if a:direction == 'below'
execute "normal! o\<Esc>"
else
execute "normal! O\<Esc>"
endif
endif
endfunction
nmap <Enter> :call <SID>insert_line('below')<CR>
nmap <S-Enter> :call <SID>insert_line('above')<CR>
Hopefully someone else will find this useful.

Resources