I am attempting to disable my touchpad whenever I enter "insert" mode. I believe this can be done with map and can be done by using a command like:
map i :silent !synclient TouchpadOff=1 <i> <CR>
map <ESC> :silent !synclient TouchpadOff=0 <ESC> <CR>
But this obviously doesn't work because map is not going to recurse to a previous definition, rather it just ignores it. How would one go about doing this?
You can setup autocommands using the events fired when insert mode is entered or left:
auto InsertEnter * :silent !synclient TouchpadOff=1
auto InsertLeave * :silent !synclient TouchpadOff=0
There may be other events you want to act upon, as well you can get a list of the known events with :help autocmd-events.
Related
I'm using a plugin that performs multiple *noremap operations in its initialization. After I added the following mapping to YCM/UltiSnips:
inoremap <expr> <CR> pumvisible() ? "<C-R>=<SID>ExpandSnippetOrReturn()<CR>" : "\<CR>"
I've broken the other plugin's ability to see the <Enter> key, or rather I overrode/destroyed the original inoremap. I want to reenable that functionality, but without disabling ability to pick snippets from the auto-complete menu using Enter key. This keymap is effectively saying "if the menu is visible, select the option, otherwise simulate <Enter> key". What I need it to say instead is "if the menu is visible, select the option, otherwise perform whatever command <Enter> key is already mapped to". So basically, at the time of declaration of this inoremap, I need to expand existing inoremap for this key into the else.
I've looked at <C-R>=feedkeys('<CR>')<CR> and <C-R>=mapcheck('\<CR>', 'i')<CR> but couldn't get either to work. Can someone help me out?
Finally figured it out... this was way more vim troubleshooting than I needed for one day.
function! LoadPumvisibleEnter()
let smartmap = maparg("<Enter>", "i")
execute printf('inoremap <script> <expr> <CR> pumvisible() ? "<C-R>=<SID>ExpandSnippetOrReturn()<CR>" : %s', smartmap)
endfunction
au VimEnter * :execute LoadPumvisibleEnter()
throwing it in a function allowed me to stay sane with escapes and which mode I was in
autocommand is needed because vim apparently runs vimrc BEFORE loading any plugins (Does Vim load plugins after loading vimrc?), so without it the map will not yet be set
I had a look at the list of events autocmd can handle, but I could not find one about search queries.
What I would like to do is to add some custom behavior after each text search is performed. I was able to remap the * command with this command:
map * *<F11>
In this case I mapped <F11> to a :call My_function() which will do something with the search pattern contained in #/.
But I still need to add my custom behavior to the / command, which is more complicated, as before it's completed it's getting the input search pattern.
Do you have any hint on how to proceed? Can I use autocmd? Or maybe is there a map trick?
An (bad) way to do it would be to remap the return key (and the esc key)
when / is pressed, something like that:
function! MyCustomBehaviour()
echo "Oui oui"
endf
function! UnmapSearch()
cunmap <cr>
cunmap <esc>
endf
function! MapSearch()
cnoremap <cr> <cr>:call UnmapSearch()<bar>call MyCustomBehaviour()<cr>
cnoremap <silent> <esc> <c-c>:call UnmapSearch()<cr>
endf
noremap / :<c-u>call MapSearch()<cr>/
It's a bad way because it's quite buggy : if you press Ctrl-C while editing the
search, it won't unmap <cr> and <esc>, then the next time you will enter : (command-line) mode,
the mappings will still be active... That's a problem that can't be solved (<c-c> can't be
remapped).
It's also a bad way because remapping directly the / key this way, IMO, is not a good practice.
But... This was the only solution I found some times ago to half-solve this problem.
Another workaround (the one I finally choose) can be written in one line :
cnoremap <c-cr> <cr>:call MyCustomBehaviour()<cr>
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
I can do <C-O>:noh<CR> when I'm in insert mode, but it doesn't work when done automatically:
autocmd InsertEnter * :nohlsearch
This works, but it behaves differently:
autocmd InsertEnter * :set nohlsearch
To clarify, what I want is to run :nohlsearch if I enter insert node, but I still want to keep the ability to do /<CR>N to search for another item.
I think, what you want can be accomplished by setting the search register directly:
:autocmd InsertEnter * :let let #/=''
If you want to restore the highlighting when returning from insert mode, you would need to save and restore the pattern, something like this should do it:
:autocmd InsertEnter * :let b:_search=#/|let #/=''
:autocmd InsertLeave * :let #/=get(b:,'_search','')
This saves and restores the current search pattern in the buffer local variable b:_search.
You should write a function calling :nohl and then redraw:
function DisableHL()
nohl
redraw
endfunction
and then autocmd InsertEnter * :call DisableHL()
I think I came up with a smart-ish way of accomplishing exactly the same effect (at least it does exactly what I want and I seem to want what you asked for).
I have this in my vimrc:
Disable highlighting when entering Insert mode
autocmd InsertEnter * set nohlsearch
Re-enable highlighting when pressing any of the nN?/ keys before sending the key, then send the key
for s:k in ['n', 'N', '?', '/']
execute('nnoremap ' . s:k . ' :set hlsearch<cr>' . s:k)
endfor
to hide last search's hightlighting
(I like to be able to quickly disable it without entering insert mode)
nnoremap <silent> <bs> :set nohlsearch<cr>
It basically sets [no]hlsearch on the fly as you use the commands.
I also checked, and at least on my setup it doesn't mess if using nN?/ as normal mode command (for vim's default commands at least) arguments (like dtN to delete until next N), although this might be a concern if you ever remap any of those keys, or if a plugin does it without you noticing it.
I have these insert mode mappings in my .vimrc file:
imap <C-e> <C-o>A
imap <C-a> <C-o>I
They make Ctrl-A and Ctrl-E move the cursor to the start and end of the line without leaving insert mode, a la emacs keybindings.
However, I just realized that the Ctrl-E mapping introduces a conflict with the autocompletion submode. The documentation in :help complete_CTRL-E states:
When completion is active, you can use CTRL-E to stop it and go back to the originally typed text.
Thus, my Ctrl-E mapping interferes with this. Is there a way that I can make Ctrl-E jump to the end of the line only if auto-completion is not active?
There is no proper way to test whether the
Ctrl+X-completion mode is active or not.
However, the following two workarounds are possible.
1. If one uses the popup menu to choose from the list of available
completions (especially in the case of menuone set in the completeopt
option), an acceptable solution might be the mapping
inoremap <expr> <c-e> pumvisible() ? "\<c-e>" : "\<c-o>A"
2. A general solution can be based on a side effect: In the
completion submode, it is disallowed to enter Insert mode recursively
(see :helpgrep Note: While completion), so if an attempt to do so
fails, we can suppose that we are in the midst of a completion:
inoremap <c-e> <c-r>=InsCtrlE()<cr>
function! InsCtrlE()
try
norm! i
return "\<c-o>A"
catch
return "\<c-e>"
endtry
endfunction