1

I have written a function which capitalises the first letter of each word like this:

function! CamelCase() range let old = getline(a:firstline, a:lastline) for line in old let x = substitute(line,'\v<(.)(\w*)', '\u\1\L\2', 'g') echom x endfor endfunction command! -range=% CamelCase <line1>,<line2>call CamelCase() 

Currently :CamelCase()displays the output in :messsages (because of echom)

How do i modify the function so it modifies the current buffer directly instead ? I have tried removing echom x and let x= but I get a large number of errors.

4
  • 2
    setline(line, substitute(...)), for one. Commented Mar 1, 2020 at 12:33
  • thank you, for some reason i had to use call : call setline(line,substitute(line,'\v<(.)(\w*)', '\u\1\L\2', 'g')) . I don't understand when to use call and when not to quite yet. Commented Mar 1, 2020 at 12:47
  • 1
    Sorry, the call was implied in my comment but I should have been explicit. function() won't work without preceding it with call or something that consumes its output (e.g.echo or variable assignment). Commands are different...they can be called straight/unadorned. Commented Mar 1, 2020 at 12:50
  • 2
    A little more explicitly, if you are using the return value of func() (examples: let foo = func(), echo func(), call otherfunc(func())) then invocation of func() is implied. If you only care about the side-effects (i.e. you want to ignore/discard the returned value) then use call to invoke func(). Commented Mar 1, 2020 at 13:11

1 Answer 1

2

You can use setline() to set the contents of a line in the current buffer.

Which, in your case, should be enough, since you're changing line contents in place and not inserting or deleting lines. (There's appendbufline() and deletebufline() which can help with that.)

Note that in your case you don't need to have your function be a range function, since the behavior of :call of a non-range function with a range is to call it repeatedly for each line in the range. So that would implicitly loop over the lines for you.

This should be enough:

function! CamelCase() call setline('.', \ substitute(getline('.'), \ '\v<(.)(\w*)', '\u\1\L\2', 'g')) endfunction 

And you can keep the exact same command definition:

command! -range=% CamelCase <line1>,<line2>call CamelCase() 

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.