42

Suppose you run the following piece of vimscript:

let @z = system("date")

This will put a string version of the current date into the z register, but the string will end with a newline that I don’t want. Is there a built-in way (similar to Perl’s chomp) to get rid of a string’s trailing newlines?

5 Answers 5

29

You can use substitute(), or define a function:

function! Chomp(string)
    return substitute(a:string, '\n\+$', '', '')
endfunction

This variant will call system for you and then chomp the result:

function! ChompedSystem( ... )
    return substitute(call('system', a:000), '\n\+$', '', '')
endfunction

(This function is also available in my ingo-library plugin as ingo#system#Chomped.)

6
  • This works, but why the weird call syntax? Why not just give Chomp a parameter called string and then pass a:string to substitute?
    – bdesham
    Commented Apr 9, 2015 at 15:03
  • 2
    @bdesham Because Chomp() is passing whatever arguments it gets on to system(), stripping the trailing newline from its output, and returning that.
    – jamessan
    Commented Apr 9, 2015 at 15:22
  • Right. system() has an optional {input} argument, and this handles any of these generically. If you don't need this, just do it the conventional way. Commented Apr 9, 2015 at 16:12
  • that looks awfully like regex, is it possible to chomp all digits as well?
    – Fuseteam
    Commented Dec 1, 2020 at 17:25
  • @Fuseteam: I'm not sure what you exactly have in mind, but if you replace \n\+$ with \d*\n\+$, any trailing digits will be removed as well. However, I probably would not combine that very application-specific cutting with the generic removal of the trailing newline, and rather do a second substitute(l:result, '\d*$', '', '') after receiving the chomped l:result, to have cleaner code. Commented Dec 1, 2020 at 17:43
28
let @z = systemlist('date')[0]

removes the newline for you.

3
  • I think this is probably the approach I’ll actually use, but I accepted the other answer because it’s more generally applicable. (For example, it will remove trailing newlines from a multiline string while leaving other newlines alone.)
    – bdesham
    Commented Apr 10, 2015 at 2:28
  • 5
    Note that this won't work correctly for systems which use something other than \n for newline. systemlist() only removes the \n, not any \r.
    – jamessan
    Commented Apr 10, 2015 at 14:12
  • 1
    Note that this will cause an error if the called function doesn't produce any output. To avoid this and get an empty string instead: get(systemlist("date"), 0, "")
    – pR0Ps
    Commented Jul 21, 2020 at 18:12
14

Vim v8.0.1630 added a trim() function that removes characters (by default whitespace) from the end or beginning (both by default) of strings:

let @z = trim(system("date"))

For more details see :help trim().

6

Christian Brabandt has listed a number of different methods over on superuser.com.

I like this one because it is short:

let @z = system("date")[:-2]
3
  • 1
    I wonder how it handles \r\n type of line endings...
    – x-yuri
    Commented Nov 16, 2018 at 16:27
  • @x-yuri That is certainly worth checking Don't quote me on this, but I think Vim-on-Windows will normalise those line-endings to \n before returning them. Commented Nov 18, 2018 at 4:33
  • Yes, with system() newlines in return values are normalized to LF (e.g. from Win32 CRLF).
    – B Layer
    Commented Jan 4, 2021 at 1:22
0
let output = split(system("ls"), "\n")

This will give you an array of the stout without newlines at the end.

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.