5

Using ]p in normal mode, I can paste a yanked line of text on a new line below the cursor with indentation equal to the current line.

Using the :put command, I can paste a yanked word as if it were a whole line, but the indentation seems to default

Is there a way to combine these two? I'm looking to be able to yank an individual word and paste it below the current line with indentation equivalent to the current line. I'm aware :put<ENTER>== would likely work, but that's slightly awkward.

2 Answers 2

4

Option 1

you can just do o<esc>p to

  1. make a new line below the current one
  2. exit insert mode without removing the auto-indentation (as opposed to
  3. paste the word at the cursor position

Just map that to something like ]P or whatever.

Option 2

You can remap ]p to add a line-break at the end if there isn't one already

nnoremap <buffer> ]p :let original=@*<CR>:let @* = substitute(@*, "\\n\\?$", "\n", "")<CR>]p:let @*=original<CR>

How does this work?

  1. Save the current value of register * into the variable original
  2. Substitute the empty match at the end of the string and optionally a single preceding newline with a newline in the string in register *
  3. Save the modified string into the register.
  4. Perform the original ]p action (because nNOREmap was used)
  5. restore the original value of the * register from the variable

Note that your vim may not use the register * for the clipboard; if the property clipboard (:help 'clipboard') is not set, vim uses the register ", on linux it may use +. In those cases you'd have to modify the mapping accordingly.

Option 3

nnoremap ]p :let [content, type] =
    \ [getreg(v:register), getregtype(v:register)] \|
    \ call setreg(v:register, content, "V")<CR>]p
    \:call setreg(v:register, content, type)<CR>

This should be even more universal than option 2, though also a bit longer and uses more functions that may seem unfamiliar to new users.

What it does is:

  1. Save the content and type of the register that vim uses for yank/put operations (:help v:register) into the variables content and type (:help let-unpack)
  2. Set the register to its previous text, but with mode "V" (line-wise)
  3. Do the default ]p operation
  4. Reset the register to its original mode

P.S.: I'm adding option 3 to my own vimrc now :)

1
  • Small tip: getreg() and getregtype() both can be called without parameters as they use v:register as the default. (@DarkWiiPlayer may have known this and included them for the sake of clarity but never the less...)
    – B Layer
    Nov 24, 2017 at 12:03
4

Tim Pope's unimpaired.vim provides [p/]p variants which force these commands to be line-wise.

If don't want to use unimpaired then you will need to cast the register as line-wise and then restore type afterwards. Here is are some mappings that are directly taken from unimaired.vim:

function! s:put(cmd)
  let [body, type] = [getreg(v:register), getregtype(v:register)]
  call setreg(v:register, body, 'l')
  exe 'normal! "'.v:register.a:cmd
  call setreg(v:register, body, type)
endfunction

nnoremap <silent> ]p :<c-u>call <SID>put(']p')<cr>
nnoremap <silent> [p :<c-u>call <SID>put('[p')<cr>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.