I am trying to remap 'e' keybind with :nnoremap e mynewcommand, but I am a bit lost about how to make the current "end of word" finish one extra position.
For example, right now if I have word1 Xword2 word3 (X being the current position), it ends here: word1 wordX word3.
Is there a way to remap it so that it ends on end of word + 1 position? Like this: word1 word2X word3
Thanks!
Edit1: For some weird reason, when doing the remap: :nnoremap <S-l> e , works like a charm - but, the :nnoremap <S-j> b doesn't work at. Does anyone have any idea?
Edit2: As requested, here is my vim.init:
:nnoremap t r
:nnoremap <SPACE> <INSERT>
:vnoremap i <UP>
:vnoremap <SPACE> <INSERT>
:nnoremap i <UP>
:nnoremap k <DOWN>
:nnoremap j h
:nnoremap <S-l> e
:nnoremap <S-j> b
:nnoremap a <S-A>
:nnoremap vv <S-V>
:vnoremap k <DOWN>
:vnoremap j <LEFT>
:nnoremap dw daw
:inoremap jh <Esc>
" Settings.
set nocompatible
set showmatch
set ignorecase
set tabstop=4
set softtabstop=4
set expandtab
set shiftwidth=4
set autoindent
set number
set clipboard=unnamedplus
set ttyfast
" Vim-plug (Plugin Manager)
call plug#begin()
Plug 'itchyny/lightline.vim'
Plug 'nvim-treesitter/nvim-treesitter', {'do': ':TSUpdate'}
call plug#end()
First: Vim (and Neovim) doesn't have "maps" so what you are doing are not "remaps", they are "mappings" (or "maps", if you really want).
Second: as someone already pointed out, f<Space> already covers your need so you probably shouldn't spend so much energy on this.
Third: <S-l> and <S-j> are convoluted and unnecessary ways to say L and J. Keep your config simple.
Fourth: :help J and :help L are two very useful commands in their own right so you should think hard about the relative benefits of overriding them. Especially for something as trivial as this.
Fifth: The in nnoremap <key> e is not very readable and is likely to disappear after some hasty formatting. You should consider these alternatives notations:
nnoremap <key> e<Space>
nnoremap <key> el
nnoremap <key> e<Right>
or maybe even:
nnoremap <key> f<Space>
Sixth: The way you explained your situation is not very clear:
word1 Xword2 word3
word1 wordX word3
Where did the 2 go? Which character was the cursor on, exactly? Could you rewrite it in a more explicit way? Something like:
Current behaviour:
word1 word2 word3
^ " position of the cursor before e
^ " position of the cursor after e
Desired behaviour:
word1 word2 word3
^ " position of the cursor before <key>
^ " position of the cursor after <key>
Seventh: I can, sort of, understand the desire for nnoremap L e<Space> because wanting the cursor to land right after the current word seems like a reasonable thing to want. You may want to put something, there, or insert a bracket, or whatever. But I fail to imagine a scenario common enough to justify nnoremap J b<Space>. What, exactly are you trying to do with that mapping? What problem are you trying to solve? And, more importantly, what does "doesn't work" mean?
Are you trying to mirror your L mapping by landing the cursor before the word? Since <Space> moves the cursor to the right, then b<Space> is obviously not going to work but the following might:
nnoremap <key> b<Left>
nnoremap <key> bh
nnoremap <key> b<BS>
or maybe even:
nnoremap <key> F<Space>
Related
Sometimes I want to swap current line with line up or below in vim. I can do it with commands :m+1 or :m-1. However it is too wordy. Is there shorter way doing the same?
give this a try:
ddp and ddkP
if it gives what you want. ;)
Both Tim Pope's unimpaired.vim - Pairs of handy bracket mappings and my own LineJuggler plugin provide (among others; my plugin has a focus on line moves and copies, whereas Tim's has a mixture of useful stuff) [e and ]e mappings to move the current line / selection above or below. These don't clobber the default register, as ddp et al. would do.
Give mappings a chance:
nnoremap <leader>k :move-2<CR>==
nnoremap <leader>j :move+<CR>==
xnoremap <leader>k :move-2<CR>gv=gv
xnoremap <leader>j :move'>+<CR>gv=gv
Vim has the :move command that allows you to move one line.
For instance, :m +1 will move the current line down.
I have these mappings in my .vimrc :
" move the lines of visual mode up or down
" JK to move and keep a correct indentation (with =)
" <up><down> to move keeping the correct indentation
vnoremap <silent> J :m '>+1<cr>gv=gv
vnoremap <silent> <down> :m '>+1<cr>gv
vnoremap <silent> K :m '<-2<cr>gv=gv
vnoremap <silent> <up> :m '<-2<cr>gv
With these lines, if you select a bunch of lines in visual mode, and then press <up> or <down> arrows, the lines will be moved up or down (and you will stay in the same visual selection thanks to the gv at the end).
J and K are almost the same, but they keep and autoindentation, using the = operator (gv= autoindents the last visual selection).
For sure, i encourage you to do modify the keys that are mapped to your own preferences. These are just mine. Also, copy-pasting without understanding is probably a bad idea. If you understand that mapping, you could check help pages for :m, gv and =.
How to move visually selected text to end of line, which command or keys I should use?
e.g. /text3<CR> note that ** is a selected text, not part of it.
**text3** text1 text2
**text3** text1 text2
and move to this:
text1 text2 **text3**
text1 text2 **text3**
I tried: :%s/\(text3\)\(.*\)/\2 \1/ any other ways to do it?
Basically you can do it (after selecting your text visually like put the cursor on your word then hit viw) with d$p. Any you can create a macro for it, I used to go with something like this in simillar cases: qq/SEARCHTERMENTERviwd$pj0q. Now you can execute it as NUMBER(s)#q.
But as a more general solution:
:%s_\(YOUR_TEXT_TO_MOVE_TO_THE_EOL\)\(.*\)_\2\1
Should work just fine.
You could use the :global command to select lines with the matching pattern and :normal to operate on those lines. For example:
:g/^text3 /norm! dt p d0$p
Explanation
:g/^text3 /<command>
Runs the specified <command> on all lines starting with text3 followed by a space. See :help :global for more information.
norm!
Executes the following commands in normal mode. See :help :normal.
dt p d0$p
Delete to the first space, paste that after said space, move forward one character and delete to the beginning of the line. Move to the end of the line and paste.
You can use Damian Conway's dragvisuals.vim
After installation add the following (uncommented) to your .vimrc
runtime plugin/dragvisuals.vim
vmap <expr> <LEFT> DVB_Drag('left')
vmap <expr> <RIGHT> DVB_Drag('right')
vmap <expr> <DOWN> DVB_Drag('down')
vmap <expr> <UP> DVB_Drag('up')
vmap <expr> D DVB_Duplicate()
" Remove any introduced trailing whitespace after moving...
let g:DVB_TrimWS = 1
Or, if you use the arrow keys for normal motions, choose four
other keys for block dragging. For example:
vmap <expr> h DVB_Drag('left')
vmap <expr> l DVB_Drag('right')
vmap <expr> j DVB_Drag('down')
vmap <expr> k DVB_Drag('up')
Or:
vmap <expr> <S-LEFT> DVB_Drag('left')
vmap <expr> <S-RIGHT> DVB_Drag('right')
vmap <expr> <S-DOWN> DVB_Drag('down')
vmap <expr> <S-UP> DVB_Drag('up')
Or even:
vmap <expr> <LEFT><LEFT> DVB_Drag('left')
vmap <expr> <RIGHT><RIGHT> DVB_Drag('right')
vmap <expr> <DOWN><DOWN> DVB_Drag('down')
vmap <expr> <UP><UP> DVB_Drag('up')
To use
Select with visual mode and move the block with h, l, j or k etc.
The solutions involving iw will work if the text is text3, but they will fail on two words.
None of the methods involving $p will add a space, as your :s command does. You could use A <C-R>"<Esc> instead.
If you want to do it on a single line, and the text is already selected in Visual mode, then x$p is pretty easy.
If the text is "selected" in the sense that you have just searched for it, and it is highlighted with the Search highlight group, and you want to make the change on a single line, then you could use d/<C-R>//e<CR>$p. The <C-R>/ will be replaced by the current search pattern, so you will get something like d/text3/e<CR>$p.
If you want to do it on all matching lines in the buffer, then a slight simplification of your solution is
:%s/\v(<C-R>/)(.*)/\2 \1
:help i_CTRL-R
:help c_CTRL-R
:help /\v
I like highlighting while searching in vim. Here's what I want:
I search for a word with /
Then, all of the results are highlighted. If I press any key other than n or N, I want the highlighting to be toggled off.
If I press n or N again after any number of commands, I want to toggle on the highlighting.
Where do I start? I'm not even sure what to google.
I have this in my .vimrc
nnoremap <CR> :noh<CR>
so that when I'm done seeing the highlighting, I just hit enter to remove it. It stays gone until I hit n or N again.
Note: If you want to keep the functionality of enter, add another <CR> on the end of the command.
I remap control-l (lower case L) so that it clears the search result as well as repaints the screen. This line in .vimrc does it:
nnoremap <silent> <C-l> :nohl<CR><C-l>
You can manually disable the last highlight with nohl.
I will let you know if I can figure out how to automate this.
One method is to setup a toggle mapping. These are some toggle mappings I have in my .vimrc:
let mapleader="\\"
noremap <silent> <Leader>th :set invhls hls ?<CR>
noremap <silent> <Leader>tn :set invnumber number ?<CR>
noremap <silent> <Leader>ts :set invspell spell ?<CR>
noremap <silent> <Leader>tw :set invwrap wrap ?<CR>
To toggle highlighting just type \th for toggle hls. The others are line number, spell checking, line wrapping. The final hls ? will display the new mode.
I prefer this, because to me it is nothing but natural.
Start searching with /<pattern> and once done, simply type <Leader>/ to stop the highlighting.
nnoremap <silent> <Leader>/ :set nohl<CR>
if some lines are too long, it will be forced to be newlined.
for example, normally a long line will looks like this
1 first line
2 this is the long second line of the file
3 third line.
but, if the window of a vim are too narrow, it will looks like this
1 first line
2 this is the long
second line of the file
3 third line
the problem arise from this.
let's assume the vim cursor are located at before 't' in 'third line'. if i type 'k', cursor will move to before 's' in 'second line of the file'. after that, if i type 'k' again, cursor will move to 'f' in 'first line'!, not 't' in 'this is the long'. what i want is that the cursor move to 't' in 'this is the long', it is more intuitive process for me. how can set my vim to works like this?
In Vim, the gj and gk commands move by line on the screen rather than by line in the file. This sounds like it probably matches your description.
You can modify your keys like this:
:map j gj
:map k gk
No, if some lines are too long and you have set wrap on they will be shown on "two lines", so to say, but there won't be a newline character between them. If you turn off wrap with set nowrap you'll see the effect.
Normally, k and j move you up and down. If you want to navigate wrapped lines use gk or gj, or just as some like it, map it to for example, the cursor keys.
nmap <up> gk
nmap <down> gj
To move in vim in a natural way is possible.
What I did was, and I suggest you, to modify (or create) your "~/.vimrc" and add these two lines:
map <C-Up> g<Up>
map <C-Down> g<Down>
This will map you control-up and control-down to the movements commands (this is coherent with control-right and control-left to move around long lines)
If you add these other two lines, you can use the same command to move in insertmode:
imap <C-Up> <C-[> g<Up> i
imap <C-Down> <C-[> g<Down> i
(VIM is great !)
Greg Ruo
This answer is derived from #mario-rossi 's answer (Kudo to him), with minor midification.
I use the normal UP and DOWN arrow key, rather than CTRL+up and CTRL+down. And somehow I need to remove one excess space in the INSERT mode mapping to avoid an off-by-one behavior.
Put the following into your ~/.vimrc:
" When a long line is wrapped, the "gk" and "gj" allow you to move up and down
" a visual line, while normal "k" and "j" move a physical line.
" The following settings map "gk" and "gj" to cursor <up> and <down>.
map <up> gk
map <down> gj
" And the following lines enables same <up> and <down> behavior in INSERT mode
imap <up> <C-[> <up>i
imap <down> <C-[> <down>i
Took this from vim.fandom.com:
There are several cases to remap up and down movements. First, you probably should remap both k/j and / arrows. Second, you should coose vim modes that requires remap. Basic modes are Normal (nmap), Insert (as after i command, imap) and Select (as after v command, vmap). To remap all three:
nnoremap j gj
nnoremap k gk
vnoremap j gj
vnoremap k gk
nnoremap <Down> gj
nnoremap <Up> gk
vnoremap <Down> gj
vnoremap <Up> gk
inoremap <Down> <C-o>gj
inoremap <Up> <C-o>gk
There's also one significant Operator mode (as in dj or, to say, y4k), remapping operator (omap) breaks vim experience/habits dramatically and not recommended.
Personally I prefer to remap Insert mode only, to keep my editorial habits intact.
I really like this vim trick to use the left and right arrows to flip between buffers:
"left/right arrows to switch buffers in normal mode
map <right> :bn<cr>
map <left> :bp<cr>
(Put that in ~/.vimrc)
But sometimes I'm munching on a sandwich or something when scrolling around a file and I really want the arrow keys to work normally.
I think what would make most sense is for the arrow keys to have the above buffer-flipping functionality only if there are actually multiple buffers open.
Is there a way to extend the above to accomplish that?
I'd rather have a completely different mapping because:
cursors are really useful, and not having them because you have a hidden buffer will annoy you a lot
some plugins use <left> and <right> because they are less obfuscated than l and h; those plugins are likely to break with such mappings
Anyway, you can try this:
nnoremap <expr> <right> (len(filter(range(0, bufnr('$')), 'buflisted(v:val)')) > 1 ? ":bn\<cr>" : "\<right>")
nnoremap <expr> <left> (len(filter(range(0, bufnr('$')), 'buflisted(v:val)')) > 1 ? ":bp\<cr>" : "\<left>")
To see documentation on the pieces above:
:h :map-<expr>
:h len()
:h filter()
:h range()
:h bufnr()
:h buflisted()
I use alt-direction to switch between buffers.
nmap <A-Left> :bp<CR>
nmap <A-Right> :bn<CR>
If you modifying hl's defaults, then the arrows would feel more useful. (Like changing whichwrap to allow hl to go past the end of line.)
I do something similar with jk to make them different from my arrows:
" work more logically with wrapped lines
set wrap
set linebreak
noremap j gj
noremap k gk
noremap gj j
noremap gk k
That will wrap long lines and jk will move to what looks like the line below. (If you have one long line, then you'll move to the part of that line below the cursor.) Great for editing prose or long comments.
See also
help showbreak
I map Tab and Shift+Tab to switch buffers when in normal mode (makes sense to my brain and the keys are not doing anything useful otherwise).
Add this to your .vimrc
" Use Tab and Shift-Tab to cycle through buffers
nnoremap <Tab> bnext<CR>
nnoremap <S-Tab> :bprevious<CR>