3

I would like to create a Vim function to prefix all selected lines with some text (it's quicker than using Ctrl-VI, etc.).

I have no experience in scripting and found this great piece of documentation and this question:

I guess, I will be using the input function to get the text to prefix with, and then will use the :'<,'>s/^/‹prefix_text›/ command to do the actual prefixing, but I have no idea about how to provide that ‹prefix_text› as a variable to be plugged into a substitute expression.

I tried this very naive solution (which, evidently, does not work because it appends input("Enter prefix text: ") only to the current line):

" Prefix lines
command PrefixLines call <SID>PrefixLines()

function! <SID>PrefixLines()
    '<,'>substitute/^/input("Enter prefix text: ")/
endfunction

Thanks for your help!

ib.
  • 27,830
  • 11
  • 80
  • 100
charlax
  • 25,125
  • 19
  • 60
  • 71
  • Ugh, too tired now to give a working solution, but read up on "execute" and "normal". Then try to copy what you usually do in normal mode with C-v I. – Rook Jan 07 '12 at 01:25
  • 3
    Why not to just use `:'<,'>s/^/prefix/` without intermediate command? – ib. Jan 07 '12 at 03:09
  • Because I'm using it all the time! – charlax Jan 07 '12 at 18:30
  • 1
    It is not obvious that typing `:PrefixLines` is faster than `:s/^/`. Probably a mapping could be more useful. For example, mapping like `:noremap i :s/^/\V` (for both Normal and Visual modes) allows you to press a shortcut, enter the prefix text, hit `Enter`, and get the text inserted. – ib. Jan 08 '12 at 00:34
  • Thanks! That's another good option. – charlax Jan 08 '12 at 02:06

1 Answers1

5

You can take advantage of the Vim substitute-with-an-expression feature that allows for the replacement string to be the result of evaluating a Vimscript expression. (See :help :s\= and :help s/\= for details.)

In your case, the expression may be as simple as a reference to the value of a local variable set to the desired prefix string via input():

command! -range -bar Prepend <line1>,<line2>call PrefixLines()
function! PrefixLines() range
    call inputsave()
    let t = input('Prefix: ')
    call inputrestore()
    exe a:firstline.','.a:lastline 's/^/\=t'
endfunction
ib.
  • 27,830
  • 11
  • 80
  • 100