4

I find that when running :echo message with a message variable that contains newlines, it displays the newline character as ^@. Often I'd prefer it to actually be split on a new line though. Do I have to split up the string manually and then make multiple calls to echo or is there a simpler way to do that?

edit: Here's an example that reproduces what I'm talking about: :echom "foo\nbar". I'm running gvim on windows

2
  • Can you be more specific about those newlines. Where is the text coming from. Are you on *nix or Windows? (Can't be regular, multi-line Vim text because that should work just fine.)
    – B Layer
    Dec 8, 2018 at 3:19
  • Ok I updated the question Dec 8, 2018 at 3:25

3 Answers 3

6

You originally mention :echo but based on your example it's :echom that is causing you issues so assuming that's right...

Some choices depending on your specific needs (e.g. do you care about the message being saved to the message history)...

:echo "foo\nbar"

:echon "foo\nbar"

:echom "foo" | echom "bar"

All of these will produce

foo
bar

Likely due to it's primary purpose being to print messages to be read by the user interactively, echom parses things a bit differently from the others. "Unprintable characters are displayed not interpreted". (Similar to the strtrans() function which also prints newlines as ^@).

2
  • Ohh I didn't realize this behaviour was specific to echom. Thanks. Dec 8, 2018 at 6:58
  • @SteveVermeulen No problem. Yeah I think the primary use case for echom, in contrast to the others, is real-time display of short messages for users. Thus you get qualities like avoiding non-printing chars and discouraging multi-line output.
    – B Layer
    Dec 8, 2018 at 8:38
0

Although the question is about echo or echomsg, from some reason echoerr acts differently, so in addition to the 1st answer given, it may worth noting echomsg's caveats:

If you want to display an error with new lines, this won't work:

echoerr 'line 1 here\n' .
 \ 'line 2 there'

Removing the . won't help. Doing this:

echoerr 'line 1 here'
echoerr 'line 2 there'

Is a bit better - but the output looks like this:

Error detected while processing function 212:
line   18:
line 1 here
Press ENTER or type command to continue
Error detected while processing function 212:
line   19:
line 2 there
Press ENTER or type command to continue

And this is probably not what one would desire - having to press these ENTER keys.

Hence, the probably best solution is:

let v:errmsg = "line 1 here\n" .
  \ "line 2 there"
echo v:errmsg
0

Vim will automatically soft-wrap echoed lines longer than &columns. Due to this perk, the following does work, although the formatting would break on screen resizes.

let msg = "Hello"

echoerr msg . repeat(" ", &columns - len(msg)) . msg

The snippet should output

Hello
Hello

You probably could create a helper function to calculate that automatically

function! EchoErrMsg(msg)
  if type(a:msg) == type("")
    let msg = split(a:msg, "\n")
  elseif type(a:msg) == type([])
    let msg = a:msg
  else
    throw "Expecting list or string as input"
  endif

  if len(msg) == 1
    let str_msg = msg[0]
  else
    for i in range(0, len(msg) - 1)
      let msg_len = len(msg[i])
      if msg_len < &columns
        let msg[i] = msg[i] . repeat(" ", &columns - (msg_len + 1))
      endif
    endfor
    let str_msg = join(msg, " ")
  endif

  echoerr str_msg
endfun

Note that this is a hack. Ideally echom would be modified in the Vim source or a new message-related could be created to allow for the same syntax echon.

Alternatively, if you simply want to display multiple lines as if it were an error, use echohl Error. Albeit simpler, unlike echomsg or echoerr, this will not save the output to the message history.

echohl Error
echon "Line 1\nLine 2"
echohl NONE

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.