I have some text yanked using yiw. Now, on another line, I want to replace text from current cursor position until end of line, so I try v$p. However, this also deletes the newline at the end of the line which I don't want to happen. How do I address this?
You can:
adjust the visual area before putting:
v$hp
use the :help g_ motion if you don't have trailing space:
vg_p
You can delete into the null register and then paste with "_Dp
Alternatively, if you want to save the text you're deleting, you can delete in the normal buffer, and past from the 0 buffer with D"0p
I find register keys clunky, so I have maps in my .vimrc for them:
" leader means "another option key like cmd or meta, but one you get to choose"
let mapleader = "\<Space>"
" get the yank register, not the thing you just deleted
nnoremap <Leader>p "0p
nnoremap <Leader>P "0P
" don't copy the thing you're gonna delete into the delete register
nnoremap <Leader>d "_d
nnoremap <Leader>D "_D
With these binds, it becomes Dp or D p depending on whether you want to keep the deleted text.
If you don't want to mess with registers at all, there's always the simple PlD.
Related
I have a few lines of codes that are too that I would like to break into 2 lines at certain location.
So instead of moving to the position then presse I to insert mode then Enter to break line then finally ESc back.
Is there way I can do it easier in normal mode only?
Many thanks.
You can define some simple mapping for it:
" <C-Enter> Insert single / [count] newline.
nnoremap <C-CR> i<CR><Esc>
Note that <C-CR> probably only works in GVIM, not in a terminal; choose a different key if necessary.
Here's an additional mapping that keeps the cursor on the original line:
" <C-S-Enter> Append single / [count] newline.
function! s:AppendCRSetPos()
keepjumps call setpos("''", getpos('.'))
return ''
endfunction
nnoremap <expr> <SID>(AppendCRSetPos) <SID>AppendCRSetPos()
nnoremap <script> <C-S-CR> <SID>(AppendCRSetPos)i<CR><Esc>g``
I have the following in my .vimrc
nnoremap S i<cr><esc>^mwgk:silent! s/\v +$//<cr>:noh<cr>`w
Which will split the line on pressing capital S.
Hope this helps
There is a vim key for that:
r<Enter>
I am trying to have a remap in my vimrc that adds a snippet, then goes to the next line in Insert mode:
:nnoremap <leader>b oimport pdb;pdb.set_trace()<esc> o
The snippet import pdb;pdb.set_trace() gets inserted into my current buffer, but the cursor in vim remains on the same line. Is there any way to have the cursor move to the next line after inserting the snippet?
For me, your mapping works, except at the end of the buffer (where it beeps and keeps the cursor at the end of the inserted line, as you report).
The reason is the space between the <esc> and o. :help <Space> is a motion (to the right, just like l), and if the cursor cannot move there (at the end of the buffer, maybe also elsewhere depending on the 'whichwrap' option), Vim beeps and aborts the mapping; i.e. all keys that come after that are ignored.
The fix is easy: Drop the superfluous whitespace, and the mapping will work everywhere!
nnoremap <leader>b oimport pdb;pdb.set_trace()<esc>o
How about this:
nnoremap <leader>b oimport pdb;<CR>pdb.set_trace()<CR>
In VIM, text block yanking in Visual Mode, and pasting the block afterwards, paste it after the desired column given by the cursor, but pastes in-place, overwriting contents of the current and following lines.
Sometimes I don't want this, what I want is to paste a block with the indentation given by the cursor position, but pasting inside new empty lines, without overwriting text.
Is there a way to do that?
Currently, to achieve this, I create a good amount of empty lines, and then paste the block, eliminating the remaining empty lines after (not very clever... ).
Note: I use set virtualedit=all to be able to paste at any column in the said empty lines.
You can try something like the following. Block-wise yank something, position the cursor and hit <Leader>p, whatever your leader key is.
function! FancyPaste()
let paste = split(#", '\n')
let spaces = repeat(' ', col('.')-1)
call map(paste, 'spaces . v:val')
call append(line('.'), paste)
endfunction
nnoremap <Leader>p :call FancyPaste()<CR>
You can of course change the mapping to be anything you want; it's just a suggestion.
Update: Here's a version that accepts an argument. This let's you e.g. paste from the system clipboard instead. It also uses virtcol() instead of col() to take account for the possible use of 'virtualedit':
function! FancyPaste(reg)
let paste = split(getreg(a:reg), '\n')
let spaces = repeat(' ', virtcol('.')-1)
call map(paste, 'spaces . v:val')
call append(line('.'), paste)
endfunction
nnoremap <Leader>p :call FancyPaste('"')<CR>
nnoremap <Leader>cp :call FancyPaste('+')<CR>
Keep in mind it will only indent with spaces, not tabs. Indenting with the appropriate amount of tabs (and spaces if needed) would require some extra lines of code, but is quite doable.
If I understand correctly what you want, you could try this based on an ex command and the = operator:
nmap <leader>p :put "<cr>'[=']
Another possibility:
nmap <leader>p :let #"=#"<cr>]p
The #"=#" seems to make Vim forget about the lines being copied, character-wise and ]p pastes reindented.
The UnconditionalPaste plugin can also help you paste like that.
I already know that gg=G can indent the entire file on Vim. But this will make me go to the beginning of the file after indent. How can I indent the entire file and maintain the cursor at the same position?
See :h ''
This will get you back to the first char on the line you start on:
gg=G''
and this will get you back to the starting line and the starting column:
gg=G``
I assume the second version, with the backtick, is the one you want. In practice I usually just use the double apostrophe version, since the backtick is hard to access on my keyboard.
Add this to your .vimrc
function! Preserve(command)
" Preparation: save last search, and cursor position.
let _s=#/
let l = line(".")
let c = col(".")
" Do the business:
execute a:command
" Clean up: restore previous search history, and cursor position
let #/=_s
call cursor(l, c)
endfunction
nmap <leader>> :call Preserve("normal gg>G")<CR>
You can also use this on any other command you want, just change the argument to the preserve function. Idea taken from here: http://vimcasts.org/episodes/tidying-whitespace/
You can set a bookmark for the current position with the m command followed by a letter. Then after you run the indent command, you can go back to that bookmark with the ` (backtick) command followed by the same letter.
In a similar spirit to Alex's answer I use the following mapping in vimrc.
nnoremap g= :let b:PlugView=winsaveview()<CR>gg=G:call winrestview(b:PlugView) <CR>:echo "file indented"<CR>
by pressing g= in normal mode the whole buffer is indented, and the scroll/cursor position is retained.
Following on top of Herbert's solution, the reader can also use <C-o>
In vim script
exe "norm! gg=G\<C-o>"
Or mapping
:nnoremap <F10> gg=G\<C-o>
Is there a vim command to directly select a block of text which has just been pasted?
ps. I know about gv to reselect a block after exiting visual mode. It doesn't apply to this case.
If you want to select it just after paste (before you change anything else), use
nnoremap <expr> gV "`[".getregtype(v:register)[0]."`]"
. [ and ] marks point to start and end of the last change, v:register is set to the last register used (which is register used for the paste command unless you, for example, yank something), [0] selects only first byte of register type (it is required because for blockwise register it returns <C-v>{width}) and register type is one byte which is just the same as the keystroke you should use in normal mode to invoke visual mode.
I saw this solution somewhere on SO, you may want to search for it in order to get some alternatives.
In my case I have this map:
:nnoremap gp `[v`]
After more research I think the better solution is:
" https://vim.fandom.com/wiki/Selecting_your_pasted_text
nnoremap <expr> gp '`[' . strpart(getregtype(), 0, 1) . '`]'
I have had the following maps in my vimrc forever:
nnoremap <leader>p `[V`]
nnoremap <leader>[ `[V`]<
nnoremap <leader>] `[V`]>
They do the following:
visually select the recently pasted block
de-indent the recently pasted block
indent the recently pasted block
I probably use the indent ones even more than the selection one.