3

enter image description here

When I paste something within normal mode, vim ignores autoindent. I copy and paste with y and p. As mentioned autoindent is on. It works fine when I manually indent or type something before pasting.

Also if I exit insert mode to normal mode right after the autoindent, the indent is lost.

7
  • I have noticed this as well. The autoindent you get when you hit enter is not really there (which is also why it gets removed as you hit enter again), as in no actual character is inserted. When you hit escape, that fake indent is also removed, I presume because otherwise vim would be inserting whitespace after end of line (which is a no no). What you see is a side effect of escape removing the indent before you paste. I personally always do a quick "some key followed by backspace" to "consolidate" the indent, then paste.
    – Shahbaz
    Commented Jul 20, 2018 at 17:28
  • @Shahbaz i did a inoremap <return> <return>yo<backspace><backspace> and it works as expected! i'm not sure if this is exactly what you meant but it worked. but still if i press <esc> the cursor goes back a full tab, but if i enter insert mode again it went back to the correct indent, and the indent seems actually there (can be selected), i don't understand why in normal mode it's ignoring the last indent..
    – tga
    Commented Jul 21, 2018 at 3:10
  • I'm surprised you are saying that going back to insert mode after <esc> puts the indent back. For me, after <esc> the indent is gone, and pressing i puts you at the beginning of the line.
    – Shahbaz
    Commented Jul 23, 2018 at 13:52
  • Personally, I've come to appreciate this behavior, although sometimes annoying. I hate whitespace after end-of-line (including empty lines that just have whitespace), and this behavior greatly helps me avoid that. With your remapping, if you press <enter><enter> to create an empty line between different pieces of your code, the empty line is gonna have the indent whitespace. In git, if you set core.whitespace to blank-at-eol for example, you're gonna have a bad time.
    – Shahbaz
    Commented Jul 23, 2018 at 13:57
  • i personally wrote a function to delete all trailing spaces on file save, but losing indent and have to smash tab all the way is straight up bad experience haha
    – tga
    Commented Jul 23, 2018 at 14:33

4 Answers 4

1

Paste from insert mode <Ctrl-r>0

You can also insert the yanked text from insert mode when autoindent has added the correct indentation:

  1. yiw yank
  2. o<CR> switch to insert mode and add new line
  3. <Ctrl-r>0 paste text from register 0

Drew Neil has created a vimcast

I would also recommend two articles by Drew Neil:

Note pasting a code block in insert mode

If you want to paste not a single word but a code block, this answer might not be satisfactory. Replace in step 1 yiw with yG and then execute steps 2 and 3, you will end up with

function Scene:get(...)

    function Scene:get(...)

            local l = {}

                for i, e in ipaires(self.nodelist) do
                            if (e:is(...)) then
                                            l[#l +1] = e
                                                    end
                                                        end

                                                            return l

                                                        end


    local l = {}

    for i, e in ipaires(self.nodelist) do
        if (e:is(...)) then
            l[#l +1] = e
        end
    end

    return l

end

To fix this you would have to set paste after you switched to insert mode to take advantage of the autoindentation because paste disables autoindentation. I do not know a simple way to do this and would recommend to paste from normal mode with the help of vim-unimpaired (=p). Also note yanking into the system clipboard and using the bracketed paste feature does not work for me flawlessly (macOS, Terminals: iTerm2.app v3.1.7 or Terminal.app v2.7.4).

7
  • 1
    Thank you for your nice answers, I can't believe I don't know about pasting in insert mode before (i was mapping <c-p> to existing insert mode, paste, and then reenter insert mode which is problematic), pasting directly in insert mode perfectly solves the problem, and thanks for the helpful links.
    – tga
    Commented Jul 24, 2018 at 17:36
  • But there's another question just about indent, if I created a function and press return, it auto indents correctly. I normally close the function before writing so I press return twice and then move up the cursor to write the content, but the indent at the second line is already gone, is there a neat way to fix that?
    – tga
    Commented Jul 24, 2018 at 17:42
  • I see your point. Going in insert mode from the line containing end with O adds the auto-indentation. My impression is that you would prefer an option which changes vim's behavior by not removing the autoindentation for empty lines when leaving insert mode. However, afaik this does not exist and I personally would not use it. Another possibility is the plugin vim-endwise. It automatically inserts end for you.
    – Hotschke
    Commented Jul 24, 2018 at 18:06
  • BTW, if this answer was the right one for you and it sounds like it, you could mark the answer as accepted. This helps other users to see if your question has been answered to your satisfaction and they can spend their time answering other questions.
    – Hotschke
    Commented Jul 24, 2018 at 18:17
  • See also following unanswered question: stackoverflow.com/questions/31436431/…
    – Hotschke
    Commented Jul 24, 2018 at 18:25
1

=p from vim-unimpaired

function Scene:get(...)

    local l = {}

    for i, e in ipaires(self.nodelist) do
        if (e:is(...)) then
            l[#l +1] = e
        end
    end

    return l

end
  1. Yank word function with yiw

  2. =p from unimpaired inserts with reindentation after the current line.

  3. Fix missing blank line with [-Space (also only with vim-unimpaired)

This is more impressive if you insert several lines from a register. For example, yank full function with yG in step 1 and then do steps 2 and 3.

1
  • There is another related plugin called vim-pasta which redefines p and P to adjust indentation w.r.t. surrounding lines. However, I did not manage to get it to work in the here discussed example.
    – Hotschke
    Commented Nov 23, 2018 at 10:35
0

gV=

Using custom mapping gV to select last changed (pasted) or yanked text.

A typical related question is how can I select a just pasted text. This would allow you to fix conveniently the indentation afterwards. By default there is no builtin keybinding for this. However, it is not difficult to define your own keybinding. IMHO gV is a good choice. Add to your vimrc

nnoremap <expr> gV     "`[" . getregtype(v:register)[0]."`]"

And now you can fix it with gV=.

The mapping is similar to gv which reselects the last selection.

Note, if you yank something else and you want to select your pasted text again, gV selects the most recent yanked text and does not help you here.

You can find the question several times on the web

0

I realized this vim's strange behavior just today.

I found a solution by chance :

]p : paste the line with the right indent

Your Answer

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

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