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?

bdesham
  • 2,983
  • 2
  • 18
  • 20

5 Answers5

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.)

bdesham
  • 2,983
  • 2
  • 18
  • 20
Ingo Karkat
  • 17,819
  • 1
  • 45
  • 61
  • 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 Apr 09 '15 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 Apr 09 '15 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. – Ingo Karkat Apr 09 '15 at 16:12
  • that looks awfully like regex, is it possible to chomp all digits as well? – Fuseteam Dec 01 '20 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. – Ingo Karkat Dec 01 '20 at 17:43
  • ah thanks for the tip my goal is more to just strip all digits rather than removing trailing newlines, substitute seemed perfect for that so i commented on this answer hehe, thanks again – Fuseteam Dec 01 '20 at 17:51
28
let @z = systemlist('date')[0]

removes the newline for you.

romainl
  • 40,486
  • 5
  • 85
  • 117
  • 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 Apr 10 '15 at 02: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 Apr 10 '15 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 Jul 21 '20 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().

pR0Ps
  • 241
  • 2
  • 4
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]
joeytwiddle
  • 3,622
  • 19
  • 28
0
let output = split(system("ls"), "\n")

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