0

I'm using vim to make my programs in c/c++ and I would like to know how can I put "\n" (which represents a newline) in my code or use "%" using :%s.

For instance, sometimes I forget to put "%" in front of "d" or "f" in many lines or forget to put "\n" in some printf() calls.

printf("This is my d code.", x);

But the following command does not work, it puts a space in place of "\n"!

:%s/\<code.\>/code.\n/gc

or

:%s/\<d\>/%d/gc

How can I do what I want?

Keith Thompson
  • 230,326
  • 38
  • 368
  • 578
claudiogc
  • 47
  • 4
  • 3
    `:%s/\/&\\n/gc` – FDinoff May 09 '14 at 14:17
  • possible duplicate of [How to replace a character for a newline in Vim?](http://stackoverflow.com/questions/71323/how-to-replace-a-character-for-a-newline-in-vim) – Konrad Rudolph May 09 '14 at 14:32
  • @KonradRudolph I don't think the OP wants a literal newline in the printf statement. I think he wants `printf("This is my %d code.\n", x);` After running the two substitutions. (c doesn't allow newlines in strings) – FDinoff May 09 '14 at 14:42
  • @KonradRudolph: It's not a duplicate. The question is about inserting the two-character sequence `\n`, not inserting a literal newline. – Keith Thompson May 09 '14 at 14:42

2 Answers2

4

The :help s/\n has the answer:

  \n    insert a <NL> (<NUL> in the file)
    (does NOT break the line)              *s/\n*

You'll also find the solution there: to insert a literal backslash, escape it \\ by doubling; to split the line, a \r has to be used. Yes, this is inconsistent, and it works differently in similar tools like sed, but that's unfortunately how it is.

Notes

  • The \n doesn't insert a space, but the special <NL> character, which usually is shown as ^@.
  • The \<code.\> isn't right; to match a literal period, you have to escape it: \.. Else, it matches any character. Likewise, the . usually isn't a keyword character, so the \> boundary wouldn't match.
  • You don't need to repeat the match text in the replacement, you can use & for it. Also read up on capture groups (:help /\() and the submatch references :help s/\1. This is a better way:
:%s/\<code\./&\\n/gc

(I don't see a problem with the second substitution.)

Ingo Karkat
  • 154,018
  • 15
  • 205
  • 275
  • 1
    I don't think he wants a literal new line. I think he wants `printf("This is my %d code.\n", x);` After running the two substitutions. (c doesn't allow newlines in strings) – FDinoff May 09 '14 at 14:38
  • @FDinoff Ah, right. I've adapted my answer. Thanks for noticing! – Ingo Karkat May 09 '14 at 15:56
3

You want to insert the two-character sequence \n, not a literal newline (the latter would create a syntax error).

A sample line to be changed is:

printf("This is my d code.", x);

One problem with your attempt:

:%s/\<code.\>/code.\n/gc

is that there is no word boundary between the . and the " following the word code. The other problem is that \ in the target is used to escape special characters (for example you can refer to a / character as \/), so the \ must itself be escaped.

This should do the job:

:%s/\<code\."/code.\\n"/gc

A more general solution might be:

:g/printf/s/"/\\n"/egc

which offers to replace " by \n" on each line that contains printf -- but that will miss any printf calls that span more than one line.

As for replacing the d by %d, the command you have in your question:

:%s/\<d\>/%d/gc

is correct.

Keith Thompson
  • 230,326
  • 38
  • 368
  • 578