How to display ^M as newline in vim? - vim

I would like to display ^M (\r) as newlines (\n) in vim. The file has both \r and \n characters. I would like to do this without:
Editing the file
Changing the way existing \n characters are displayed
Having to do a search and replace every time I open the file
In short, the same way Notepad++ displays them.

Related

Vim listchars showing end of line when there is no newline char

Create a new text file with notepad, type in 'hello world' and do not press enter at the end. Save the file.
This file has no newline character at the end of the file. Hex editor confirms this.
Yet opening the file in Vim, and turning on set list, the listchars shows the eol character. Why? Bug?
I've googled and I understand why Vim chooses to automatically write eol chars, and that I can turn that off using set nofixeol. But that is irrelevant to this.
The question I have is:
How do I get Vim to only display newline chars that actually exist in the file? Clearly listchars does not do this
From a quick google, the answer to my question is, its not possible:
https://github.com/vim/vim/issues/6119

fs.readFileSync adds \r to the end of each string

I'm using let names = fs.readFileSync(namefile).toString().split("\n"). Whenever I do
for(const name of names) {
console.log(`First Name: ${name.split(" ")[0]} Last Name: ${name.split(" ")[1]}
}
the last name part always has \r at the end, how do I make it not add the \r?
fs.readFileSync doesn't add anything to the end of lines,
instead the file that you're trying to read is using CRLF line endings, meaning that each line ends with the \r\n sequence.
Really your file looks something like this:
line1\r\nline2\r\nline3\r\n
But your text editor will hide these characters from you.
There are two different ways you can fix this problem.
Change the type of line endings used in your text editor
This is IDE specific but if you use Visual Studio Code you can find the option in the bottom right.
Clicking on it will allow you to change to LF line endings, a sequence where lines are followed by a single \n character.
Replace unwanted \r characters
Following on from your example we can use .replace to remove any \r characters.
let names = fs.readFileSync(namefile)
.toString()
.replace(/\r/g, "")
.split("\n")
More on line endings

Exact selected multiline string search in vim

I have a buffer. In that buffer exists a string that spans multiple lines:
asdf
qrughatuxlnjtzu
... tens more lines...
I have one instance of this string readily available under my cursor. I want to search for other instances of this multiline string in the same buffer without having to manually copy/edit significant portions of said multiline string into the command buffer (n.b. manually replacing newlines with their regex equivalents is significant editing).
I've tried using How do I search for the selected text? (visual selection -> yank -> command buffer) + Exact string match in vim? (Like 'regex-off' mode in less.) (verbatim search), but the approaches do not appear to work for multiple lines.
How do I perform an exact multiline search of a selected string in Vim?
nnoremap <your keys> :<c-u>let #/=#"<cr>gvy:let [#/,#"]=[#",#/]<cr>/\V<c-r>=substitute(escape(#/,'/\'),'\n','\\n','g')<cr><cr>
Then visually select the lines with V (or v for part of lines), and then hit <ESC> and <your keys>.
Source is here (see answer by #Peter Rincker).
You could just search with \n as newline:
/asdf\nqrughatuxlnjtzu
Depending on the newline characters that are in your file you can include the end of line characters in your search too,
e.g. for Unix line endings you can search for
/asdf\nqrughatuxlnjtzu$
for windows line endings you'd use \r\n instead.
The $ character above will search to the end of the line so will exclude any line endings but this is necessary to avoid matching on lines such as
asdf
qrughatuxlnjtzuNotToBeMatched
Also see http://vim.wikia.com/wiki/Search_across_multiple_lines
I'd map * to search visual selected region with this:
vnoremap * "vy/\V<C-R>=substitute(escape(#v,'/\'),'\n','\\n','g')<CR><CR>

^M vs \n in vim string replacement

There seems to be some sort of asymmetry in the way Vim treats ^M when doing string replacement (:s/x/y/).
Perhaps an example is best; say we have this text file:
foo:bar:biz
I want to split this into lines. This works fine:
:s/:/^M/g
(note that ^M is produced by typing Ctrl-V, Enter)
This results in the text file:
foo
bar
baz
Now, if I undo that and try again, I notice that this does not work:
:s/:/\n/g
Here, the resulting text is:
foo^#bar^#biz
That is to say, they are joined by the ASCII NUL byte (0x00).
Question 1: Why does using \n in the replacement result in NUL bytes?
Now, I figure "okay, I guess ^M is used as the 'line separator' character in some way, for Vim; I can work with that".
So I do another experiment, starting with the one-item-per-line text file:
foo
bar
baz
and now, I want to join them with colons, so it looks like the very first incarnation, above.
So I run:
:%s/^M/:/
But this fails, with the error:
E486: Pattern not found: ^M
However, this command does work:
:%s/\n/:/
producing:
foo:bar:biz:
(I can get rid of the trailing colon myself)
So Question 2: Why does \n work in this case, where ^M does not?
And ultimately, Question 3: Why is there this asymmetry between \n and ^M depending on whether it's on the right- or left-hand side of a string replacement command?
When searching, \n is a "catch-all" atom that conveniently matches any kind of "end-of-line": CRLF, CR, and LF.
When replacing, \n is <Nul> and represented as ^#.
When replacing, \r is the legal "end-of-line" for the current fileformat.
In short, get used to this pattern and carry on:
:s/\n/\r
See :help NL-used-for-Nul and CR-used-for-NL.

Viewing \n and \r characters in Vim?

Is there a way to make \n or \r characters visible in vim? (I want to be able to see if the csv file I am looking at uses just \n or \r and \n at the end of lines.
:setl fileformat?
dos means CR-LF (consistently; if only some lines contain both, it'll be listed as unix, and you'll see ^M characters at the end of those lines), unix means LF; mac means only CR newlines.

Resources