vim mapping ctrl-; - vim

In my case the move-right button is ;
I want Ctrl; to move the cursor 7 characters to the right.
I've tried the below .vimrc mapping, but it doesn't work:
nmap <c-;> 7;

Like previous comment says, it seems that ";" cannot be in the form <C-;>.
You can test typing Ctrl+V + key sequence.
Ctrl+V + ; gives only ; whereas Ctrl+V + L give ^L.
So I suppose that vim cannot recognize <C-;>.
You have some more information on the key codes help pages:
:help keycodes
:help <C-

I am not sure, but it might be because <C-;> does not map to an ASCII character. Only #, A-Z, [, \, ], ^ and _ map to ASCII characters (0 through 31 respectively) when combined with Ctrl.
EDIT
I did some searching and found this thread. In it, it is said that gvim.exe works the way I suggest: only use valid control characters, no other. Interestingly vim.exe works differently and you can do the mapping you want.

As others said <c-;> can't be mapped.
The best solution is:
nmap <C-l> 7l
nmap <C-h> 7h
You can remap the regular cursor keys instead.
something like this also would work:
nmap <C-Right> 7l
nmap <C-Left> 7h
Other side example for resizing windows:
" resize horzontal split window
nmap <C-Up> <C-W>-<C-W>-
nmap <C-Down> <C-W>+<C-W>+
" resize vertical split window
nmap <C-Right> <C-W>><C-W>>
nmap <C-Left> <C-W><<C-W><

You can hack your keyboard by using sxhkd + xkvbd. Just to give you an idea I was able to map C-LefMouse so my system recognize as if it was MiddleMouse:
# put this in your sxhkdrc
ctrl + button1
xvkbd -no-jump-pointer -xsendevent -text '\m2'
~/.config/nvim/lua/core/utils
local M = {}
-- https://blog.devgenius.io/create-custom-keymaps-in-neovim-with-lua-d1167de0f2c2
-- https://oroques.dev/notes/neovim-init/
M.map = function(mode, lhs, rhs, opts)
local options = { noremap = true }
if opts then
options = vim.tbl_extend("force", options, opts)
end
vim.api.nvim_set_keymap(mode, lhs, rhs, options)
end
return M
In our mappings.lua
local map = require('core.utils').map
-- copy to the primary selection on mouse release
map("v", "<LeftRelease>", '"*y')
map("i", "<C-MiddleMouse>", '<C-o>"*p')
map("n", "<C-MiddleMouse>", '"*p')
The idea is to make nvim recognize your Ctrl+; as if it was something it can handle, similarly as I did with this primary selection solution. Eventually, these ideas could help someone figure out solutions for other issues.

In KDE konsole terminal, you can add key bindings.
terminal right click menu --> Edit Current Profile --> keyboard --> Edit
I have added a value like this:
Key Combination => ;+Ctrl
Output => \E[9;8~
then you can check the value with Ctrl-V Ctrl-; in termnal.
if successfully printed ^[[9;8~ then you can use the value in vim key bindings something like this
inoremap ^[[9;8~ <esc>A;
you also need to type Ctrl-V Ctrl-; for the value after inoremap

Related

VIM: set term=xterm changes <BS> to <Del>, is it reversible?

I have added set term=xterm to my vimrc to be able to use 256-color vim schemes in terminal, but it comes at a price (at least for me). It also replaces (sort of) the BackSpace with Delete (i.e. BackSpace starts to delete forward just like Delete does) in insert mode and makes it "BackSpace" instead of moving left (or h) in normal mode. I have nothing against Ctrl-H as a way "to Backspace", but I simply don't want to have two delete buttons and ability "to BackSpace" (delete backward) in normal mode.
How can I reverse that change while retaining the setting I need?
PS I've read :h CTRL-h and a bit of :h xterm, but I couldn't find the solution.
Vim's inoremap and nnoremap commands can be used to adjust how keys are interpreted in Vim.
A solution is documented here for your specific context: https://conemu.github.io/en/VimXterm.html
The relevant quote:
"If you have problems with BS in Vim (BS acts like Delete key) under ConEmu when term=xterm, you may try to remap BS key:
inoremap <Char-0x07F> <BS>
nnoremap <Char-0x07F> <BS>
"
In general, when a key does not do what you want, the trick is to find out what it actually sends to Vim. Sometimes hitting Ctrl-V followed by that key in insert mode might help figure it out. Then inoremap and nnoremap as shown above can be used to reassign it to the behaviour you want in insert and normal modes, respectively.

Select a different keystroke than colon ':' to enter command-line mode in vi

Is there any way to achieve that remapping? I looked a bit into
map
and
inoremap
but they appear to affect within a given mode, not how to enter a given mode.
You could use nmap, e.g.,
:nmap ; :
to map semicolon to colon. The 'n' in nmap indicates normal mode.
If you wanted to use, say, the <F2> function key to enter command-line mode from insert mode, you can do:
:imap <F2> <Esc>:
There's an exhaustive 3-part tutorial about key mappings in vim here.

How can I map the '<' key in vim?

I would like to create the map
:map <F2> :map <F12> etcetcmy_map
which would have the result of: when I hit <F2>, the string map <F12> etcetcmy_map is typed into my console. but I'm having problems mapping the < key/char. Most pointedly, this is not being done; the string isn't being typed into my console. What happens instead is the the char under the cursor is case fliped (from upper to lower and vice versa) and then the cursor is moved forward by 1 char.
I've tried reading the documentation and have tried the Ctrl-V method, but I'm not getting it right. Does anyone how to do this, or if it is possible?
In your mapping's right-hand side, the <F12> is executed as a key press of the F12 key (with the unexpected side effects you've described), but you want a literal insertion of the string <F12>. For that, escape the < char as <lt>:
:map <F2> :map <lt>F12> etcetcmy_map
Also, you should use :noremap; it makes the mapping immune to remapping and recursion.
If you want to map F12 to etcetcmy_map when you press F2, you can:
:map <F2> :map <F12> etcetcmy_map<cr>

Move to the beginning of line while in Insert mode

I know that I can use either:
Home in insert mode
Esc + i to exit insert mode and enter it again, effectively going to the beginning of line.
But neither satisfies me. In first case I have to tilt my head to hit Home, because I can't blindly hit it. In second case my left arm has to leave the home row to hit Esc, which is annoying too.
Any thoughts?
Ctrl+O whilst in insert mode puts you in command mode for one key press only. Therefore Ctrl+O then Shift+I should accomplish what you're looking for.
You could enter insert mode using I (capital i).
It will put the cursor at the beginning of the line.
Similarly you can use A to add something at the end of the line.
Though, it does not really solve the problem of moving while already being in Insert mode.
I have just checked help on Insert mode, there is no key combination in insert mode to move at the beginning of the line.
Other idea :
Remap a new command only in insert mode
inoremap <C-i> <Home>
I've got Ctrl+a and Ctrl+e mapped to beginning and end of line, respectively. This matches the behavior of most bash command lines. Works well for me.
inoremap <C-e> <Esc>A
inoremap <C-a> <Esc>I
If you are using MacOS Terminal go to Preferences...>Settings>Keyboard and map the end key to Ctrl-O$ (it is displayed as \017$) and then use fn+left to simulate the end key. Do the same for the home key. Escape sequence \033[H also works for home.
Your best course of action is to remap the action to a different key (see How to remap <Ctrl-Home> to go to first line in file? for ideas)
I'd think of how often I use this "feature" and map it to a keystroke accordinly
You can map the keys to this:
inoremap II <Esc>I
ref: http://vim.wikia.com/wiki/Quick_command_in_insert_mode
A shortcut that has worked for me (both muscle memory and intuitiveness) is to map __ (which is a double _) to "insert at start of current line".
Rationale:
_ already goes to the start of line
in vim, doubling anything is a very common way of doing that "to this line"
double _ doesn't conflict with any motions (you're already at the start of line)
your hand is already in the right place if you went to the beginning of the line and now want to insert.
vimscript:
"insert at start of current line by typing in __ (two underscores)
function DoubleUnderscore()
if v:count == 0 && getcurpos()[2] == 1
:silent call feedkeys('I', 'n')
else
:silent call feedkeys('^', v:count + 'n')
endif
endfunction
nnoremap <silent> _ :call DoubleUnderscore()<CR>
It's this complicated because the easy alternative nnoremap __ _I causes vim to delay on pressing _ to distinguish between _ and __.
ctrl+o then 0
| |
letter number
i use this command to go to end of line without leaving insert mode
inoremap jl <esc><S-a>
Similarly to go to beginning of line will be:
inoremap jl <esc><S-i>

Quickly switching buffers in Vim normal mode

Recently I found out that I'm "using tabs incorrectly" in Vim. I've been trying to just use buffers in Vim since, assisted through MiniBufExplorer, but I find it painful because of how many keystrokes it takes to change buffers from normal mode. With tabs, I can just do gt or gT to hop back and forth between tabs in normal mode, and I can also do NUMBERgt to go to a specific tab.
With buffers, I either have to enter command mode with :bn, :bp, or with MiniBufExplorer, use Ctrl + k or Ctrl + Up to hop up to the buffer window, scroll left or right with h and l and then hit Enter to select the buffer I want. Or I can do something involving a leader sequence, but it always requires removing multiple fingers away from home row. That's a real pain.
How can I get something equivalent switching tabs in normal mode to switch buffers in normal mode, so I can do something like gn/gp for :bn/:bp and NUMBERgn for :buf NUMBER?
Add this to your .vimrc
map gn :bnext<cr>
map gp :bprevious<cr>
map gd :bdelete<cr>
" I personally use <leader>
map <leader>n :bnext<cr>
map <leader>p :bprevious<cr>
map <leader>d :bdelete<cr>
Note that you are remapping gp and gd, but maybe you don't care about that (:help gp, :help gd).
For more information on how to map key strokes see :help map-overview and :help map.txt.
Btw, I personally use <leader> instead of g in the mapping. My <leader> is set to ;. This puts my <leader> key on the home row which makes me willing to map all kinds of stuff using <leader>. :help mapleader if you want to change your <leader> key.
The way I usually switch between buffers is to use the :buffer command with the built-in autocompletion, e.g. :b prof<Tab> to switch to folder/path/LoginProfileFactory.php.
You can just start typing any part of the file name of the buffer you need, which is nice.
Less often, I actually remember the numbers of the buffers I want and I use something like :b 3 or :3b.
I see you mention you don't like :buf 3 though, so Rumple Stiltskin has an alternative to the :3b style that you may prefer.
{count}CTRL-^ switches to the count numbered buffer.
I have the following lines in .vimrc:
nnoremap <silent> <tab> :if &modifiable && !&readonly && &modified <CR> :write<CR> :endif<CR>:bnext<CR>
nnoremap <silent> <s-tab> :if &modifiable && !&readonly && &modified <CR> :write<CR> :endif<CR>:bprevious<CR>
Now a Tab let you go to the next buffer and a Shift-Tab to the previous.
This is based on Nick Knowlson's answer, but I wanted to expand on my comment there ...
Type :b <Tab> (note the space), then cycle through the open buffers with Tab or ← / →.
... which gets us closer to the Ctrl + Tab in all the other editors and browsers I use.
It's actually even better in some ways, you can then go backwards and forwards with ← / → arrows. It avoids the thumb + finger fu to type Ctrl + Shift + Tab to go backwards through the tabs in editors and browsers.
N.B. Shift + Tab just does the same as Tab
This is then actually something like Win + Tab in Windows 10, where once you first open up the window and you can then move around using the arrow keys.
Edit: I have two further tricks that I picked up for using buffers:
From this answer I have this in my .vimrc:
nnoremap <leader>bb :buffers<cr>:b<space>
it opens the :ls / :buffers command and pre-types the :b so that you just have to type the buffer number as you'll see a list with all the buffers and their numbers.
I also have
nnoremap <leader><tab> :b#<cr>
which toggles between the current and most recently used buffers, it's a bit like doing cd - when switching back and forth between directories
I use the plugin unimpaired.vim
it defines mappings [b and ]b that jump to the previous and next buffer in the list.
For jumping for a specific buffer the best option I know is the one you mentioned: :b<number>
If you go into another buffer you can came back quickly by typing <c-^>
Expanding on Rumple Stiltskin's answer, if you know that the file you want to get to is in buffer 4, for example, you can get there quickly with
4Ctrl-^
On my UK keyboard, I can actually do 4Ctrl-6, as explained in
:help CTRL-^
By the way, you can see the buffer numbers with
:buffers
or
:ls
I use LustyExplorer: I hit <leader>b to open a list of buffers then a couple of letters from the name of the buffer I want to open then enter. Easy.
But, you are not "using tabs incorrectly", you are using tabs the way you want. If it worked for you why go through the pain of unlearning your way to learn "the right way"?
I use F9 and F10 to move between the previous/next buffer with this mapping:
map <F9> :bprevious<CR>
map <F10> :bnext<CR>
For me this is the fastest way to switch buffers.
fzf.vim is another fast way to changes buffers using fuzzy matching. This plug-in ships with the default command:
:Buffers
which opens the list of all open buffers similar to :ls but a buffer can be (fuzzy) searched and selected.
Opening the buffer in the current window is through enter, but can can also be opened in a new split (h or v) or tab using ^X ^V or ^T respectively.
Noteworthy is also:
:Lines
Which allows to search through the content of all open buffers. This can be handy if you forget the name of a buffer but you know what it should contain.
Here is my solution:
" `<leader><Tab>` - next buffer;
nnoremap <silent> <leader><Tab> :bnext<CR>
" `<leader><S-Tab>` - previous buffer;
nnoremap <silent> <leader><S-Tab> :bprevious<CR>
" `_bufferNumber_ + <Tab>` - go exact the buffer number;
nnoremap <silent> <Tab> <C-^>
By the way, I use 'buftabline' plugin and set let g:buftabline_numbers = 1 to spread my buffer on the tabline.
I make it easier for myself:
In .vimrc :
nnoremap <leader>bf :buffers<CR>:buffer "<- Last spaces is necessary
For example, in normal mode, say your leader key is \(default it is), type \bf, then you have a list of opened buffers, type number of buffer you want and hit enter key.
NOTE: remember that last spaces not necessary at all if you wich type it after :D
Jut like that ;)
More detail:
<C-O> Navigate backward
<C-I> Navigate forward
So there is no need extra remapping, otherwise you remapped them.
I think bufexplorer is a nice plugin to use. <leader>be brings up an interactive buffer explorer that lists all open buffers. You could quickly move through the list and Enter puts you in the selected buffer. Unlike LustyExplorer It has no dependency to ruby.
I prefer navigating between buffers similarly to how I'm navigating between window panes: <alt-h> and <alt-l>. This is to straightforward to set on Mac because <alt>/<option> key binds are bounded to specific characters.
" Buffer navigation
map ˙ :bp<cr>
map ¬ :bn<cr>
map § <c-^>
Here is a good answer that shows how you can see characters maped to <alt-..> combinations

Resources