Search code examples
vimautocmd

vim function only works properly the first time


I wrote a function in vim to insert text in "paste"-mode. If I leave the insert mode, the script also leaves the paste mode (set nopaste). Therefore I used the autocommand InsertLeave.
The Problem is, that the "set paste" command works only the first time I call the function. If I want to call it once more I have to restart vim.

This is the vim function:

function Paste_from_clipboard()
    execute "normal! :set paste\<CR>\<Esc>o"
    execute "startinsert"
    autocmd InsertLeave * execute "normal! :set nopaste\<CR>"
endfunction

map <Leader>p :call Paste_from_clipboard()<CR>

What did I do wrong?


Solution

  • I think you are misunderstanding how VimScript works. Every line (be it on .vimrc, a plugin, a syntax file) is just an ex command, where the starting : is not needed. So when you write this:

    execute "normal! :set paste\<CR>\<Esc>o"
    

    You're basically calling a ex command (:exec) which calls another ex command (:normal) which then simulates normal mode to what? To call yet another ex command (:set) and using key codes to execute it. Why? You can just use the final ex command directly:

    set paste
    

    This is also happening in your auto command. Also, it is important to notice that you're recreating an auto command every time you call your function. A simple fix is then to remove your extra commands and move the auto command outside the function, so it is created only once. The execution will then happen every time the event is triggered (without another event listener being created over and over.

    function Paste_from_clipboard()
        set paste
        startinsert
    endfunction
    
    autocmd InsertLeave * set nopaste
    
    map <Leader>p :call Paste_from_clipboard()<CR>
    

    Check the :h pt for the pastetoggle option. It might be an alternative to what you are doing.