Mapping the f keys to symbols not always working - vim

I'm trying to map all the function keys to the corresponding symbols. This is what I have put in my .vimrc:
:noremap! <F1> !
:noremap <F1> !
:noremap! <F2> #
:noremap <F2> #
:noremap! <F3> #
:noremap <F3> #
:noremap! <F4> $
:noremap <F4> $
:noremap! <F5> %
:noremap <F5> %
:noremap! <F6> ^
:noremap <F6> ^
:noremap! <F7> &
:noremap <F7> &
:noremap! <F8> *
:noremap <F8> *
:noremap! <F9> (
:noremap <F9> (
:noremap! <F10> )
:noremap <F10> )
:noremap! <F11> _
:noremap <F11> _
:noremap! <F12> +
:noremap <F12> +
Although it works with the insert, command-line and replace modes it does not work e.g with the r,f and t commands. There appears to be no conflict when I check with the :map command.

The vim help for f reads
f{char} To [count]'th occurrence of {char} to the right. The
cursor is placed on {char} |inclusive|.
{char} can be entered as a digraph |digraph-arg|.
When 'encoding' is set to Unicode, composing
characters may be used, see |utf-8-char-arg|.
|:lmap| mappings apply to {char}. The CTRL-^ command
in Insert mode can be used to switch this on/off
|i_CTRL-^|.
Based on this, I think you would need to also do
:lnoremap <F1> !
:lnoremap <F2> #
" etc
I also found that I had to use CTRL-^ in insert mode as the manual suggests before the mappings would apply to f and t (the default was to ignore the lmapings).

As Johnmastroberti pointed out, indeed you need to use lmap to achieve your goal.
The CTRL-^ trick actually controls iminsert variable. You can set it manually with
:set iminsert=1
But the problem you can struggle with is clever-f plugin as it replaces default f behaviour and (I can be wrong here but didn't find such option) do not allow to use lmapping.

Related

Vim mapping for diffget | diffput not working with v:count

Pretty new to mappings in Vim,
In Diff Mode I've got C-Up and C-Down mapped to [c and ]c for diffjumping. I'm wanting to map C-Right and C-Left to :<C-U>diffput v:count<CR> and :<C-U>diffget v:count<CR> respectively to speed up merging.
nnoremap <C-Left> :<C-U>diffget v:count<CR>
nnoremap <C-Right> :<C-U>diffput v:count<CR>
nnoremap <C-Up> [c
nnoremap <C-Down> ]c
This should.... put from buffer # or get from buffer #.
But I get the error "no matching buffer for v:count".
the command looks to be taking v:count literally and running :diffget v:count instead of :diffget 3 for example.. how do I get v:count to resolve to a number? like dereference the variable?
I can echo "diffget v:count" and that looks to be correct... but obviously doesn't do anything...
Found the answer in vi.SE
<expr> <C-Left> ":\<C-U>diffget " .. v:count .. "\<CR>"

Vim <A-j> Keybinding for 10j moves cursor to the right

I've recently mapped 10j to <A-j> and 10k to <A-k>, which is seemingly quite amazing, but there is one problem with it:
When I normally type 10j (not using the shortcut), it will just move 10 rows down vertically but not move horizontally at all (given the lines have the same length), but when I use <A-j> it will always (well, interestingly enough, not always, but most of the times) also move one letter to the right.
Funnily enough, this happens only for <A-j>, whereas <A-k> works as intended. How can I prevent that? And maybe most importantly: Why is that?
If it helps, these are my other keybindings:
nnoremap K K<C-w>L
nnoremap <A-h> :set hls!<cr>
nnoremap / :set hlsearch<cr>/
nnoremap <A-j> 10j
nnoremap <A-k> 10k
nnoremap <A-w> W
nnoremap <A-b> B
nnoremap <A-v> V
nnoremap <A-m> '
nnoremap <A-p> "+p
nnoremap <A-y> "+y
nnoremap <A-4> $
nnoremap <A-3> 0
nnoremap Y y$
vnoremap <A-h> :set hls!<cr>
vnoremap / :set hlsearch<cr>/
vnoremap <A-j> 10j
vnoremap <A-k> 10k
vnoremap <A-w> W
vnoremap <A-b> B
vnoremap <A-v> V
vnoremap <A-m> '
vnoremap <A-p> "+p
vnoremap <A-y> "+y
vnoremap <A-4> $
vnoremap <A-3> 0
Yeah, I like the alt-key a lot.
You have a trailing space character at the end of your mapping:
:nnoremap <A-j>
n <M-j> * 10j<Space>
<Space> is the same command as l; it moves a character to the right (where possible).
The right-hand side in a mapping is taken literally (up to the end of the line or a | command separator). Another common mistake is appending a " comment to a mapping definition.
Plugin recommendations
If you regularly stumble over trailing whitespace (it's generally frowned upon in many coding styles, and tools like Git also highlight it as problematic), my ShowTrailingWhitespace plugin can alert you to those, and the DeleteTrailingWhitespace plugin can remove them for you. (The plugin pages have links to alternative plugins.)

vim: visual star search not working as expected

I copied this function to visually search with * and #:
function! s:VSetSearch(cmdtype)
let temp = #s
norm! gv"sy
let #/ = '\V' . substitute(escape(#s, a:cmdtype.'\'), '\n', '\\n', 'g')
let #s = temp
endfunction
xnoremap * :<C-u>call <SID>VSetSearch('/')<CR>/<C-R>=#/<CR><CR>
xnoremap # :<C-u>call <SID>VSetSearch('?')<CR>?<C-R>=#/<CR><CR>
The # mapping works fine but the * mapping doesn't exit visual selection (it extends the range of the visual selection until the next searched word). I don't understand why this is happening. Is there a solution?
EDIT: To reproduce the problem save the code snippet, download the MS Installer, open cmd.exe and start vim vim -u NONE, then do :set nocp and finally source the saved code. In fact, the following simple mapping doesn't work either:
nnoremap * *<C-o>
EDIT 2: Can someone else reproduce this issue? Should it be reported?
EDIT 3: I believe that the problem (bug?) is that the * (star) key cannot be remapped: if I start vim with vim -N -u NONE (Vim 7.4 with patches 1-274) and run the command :noremap * :echo "star"<CR> and press *, vim tries to perform a search. I also reported this to the vim dev group.
The following is what I use :
function! s:Vword()
return getline('.')[col("'<")-1:col("'>")-1]
endfunction
xnoremap <silent> * <Esc>/\v<<C-R>=<SID>Vword()<CR>><CR>
xnoremap <silent> g* <Esc>/\v<C-R>=<SID>Vword()<CR><CR>
xnoremap <silent> # o<Esc>?\v<<C-R>=<SID>Vword()<CR>><CR>
xnoremap <silent> g# o<Esc>?\v<C-R>=<SID>Vword()<CR><CR>
nnoremap <silent> g// :grep -w <cword> <C-R>=getcwd()<CR><CR>
nnoremap <silent> g/* :grep <cword> <C-R>=getcwd()<CR><CR>
xnoremap <silent> g// :<C-U>grep -w <C-R>=<SID>Vword()<CR> <C-R>=getcwd()<CR><CR>
xnoremap <silent> g/* :<C-U>grep <C-R>=<SID>Vword()<CR> <C-R>=getcwd()<CR><CR>
I have also additionally added nice mappings for g* & similarly g# and also a bunch of mappings for invoking grep that I find very useful.
Edit: minor fixes to code.
Mapping <kMultiply> instead of * solved the problem. Really strange since I do not use the keypad multiply key.

using variable and expressions in search and replace command

I am trying to set some key mapping/macros to comment/uncomment blocks of text in my .vimrc but I can't manage to make it work.
I define some variables:
let g:comment_id='~'
autocmd BufRead,BufNewFile *.c,*.cpp,*.cxx,*.h,*.hpp,*.hxx,*.ipp let b:comment_open='//'
autocmd BufRead,BufNewFile *.f90,*.F90 let b:comment_open='!'
And then I try differents ways to use them but everytime it fails:
noremap <silent> ,cc :s/^/<C-R>=(b:comment_open.g:comment_id)/<CR>:nohlsearch<CR>
noremap <silent> ,uc :s/<C-R>=(b:comment_open.g:comment_id)//<CR>:nohlsearch<CR>
->
E15: Invalid expression: /,
E15: Invalid expression: (b:comment_open.g:comment_id)//
noremap <silent> ,cc :s/^/<C-R>=(b:comment_open.g:comment_id)<CR>/<CR>:nohlsearch<CR>
noremap <silent> ,uc :s/<C-R>=(b:comment_open.g:comment_id)<CR>//<CR>:nohlsearch<CR>
->
E488: Trailing characters
noremap <silent> ,cc :s/^/\=(b:comment_open.g:comment_id)/<CR>:nohlsearch<CR>
noremap <silent> ,uc :s/\=(b:comment_open.g:comment_id)//<CR>:nohlsearch<CR>
->
cc: ok,
uc:
E64: \= follows nothing,
E476: Invalid command
I fact I can't understand how 'C-R' and \= work and mean...
Thanks for your help
Use:
nnoremap <silent> ,cc :s/^/\=b:comment_open.g:comment_id/<CR>:nohlsearch<CR>
nnoremap <silent> ,uc :s#\V<c-r>=escape(b:comment_open.g:comment_id,'\#')<cr>##<cr>:nohlsearch<cr>
Reference: :help sub-replace-expression
It is necessary in the pattern to turn verynomagic on to escape all special characters, and even with that you need to escape both the delimiter and the backslash.

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