1

Trying to find a linefeed within a binary file using vim -b, but any attempt at entering that byte value (e.g. control-v control-j, control-v 010, control-v u000a) turns into a NUL (^@) instead.

I've tried using vim 8.2.2029 and neovim v0.5.1 on MacOS Big Sur 11.6 along with vim 8.1.2269 in Ubuntu 20.04, observing the same behavior in each.

Mark Reed
  • 226
  • 1
  • 5
  • Not an answer but per :h keycodes this is apparently by design <NL> linefeed CTRL-J 10 (used for <Nul>). Wonder why... – B Layer Nov 08 '21 at 18:02
  • You could always temporarily filter the file through xxd (:%!xxd) and search for the hex value. Then undo to reverse. (Do NOT save! :) – B Layer Nov 08 '21 at 18:08
  • 1
    Importantly that filtering is best done with vim -b or :edit ++bin; otherwise you are likely to corrupt the file. My Hex plugin has some conveniences for that, but you still have to remember binary mode – D. Ben Knoble Nov 08 '21 at 18:31
  • 1
    Or rather corrupt the buffer contents since the file won't be impacted as long as no saving is done. – B Layer Nov 08 '21 at 20:00
  • Apparently it's because lines are stored as NUL-terminated strings; it can't put an actual NUL character inside such a string, so it puts a LF instead. And the linefeeds in the file mark the boundaries between strings but are not themselves actually stored in memory – apparently not even in binary mode. <Nul> zero CTRL-@ 0 (stored as 10) *<Nul>* – Mark Reed Nov 08 '21 at 21:23

1 Answers1

1

This is apparently by design. Internally, each line of the file is stored as a NUL-terminated string. The actual linefeeds from a file are not stored at all; they simply delimit the strings when a buffer is read from or written to a file. LF-valued bytes only show up in buffer memory to represent NULs, since there's no way to put a literal zero byte inside a NUL-terminated string.

So I guess the way to search for a linefeed value even in binary mode is to do a regex search for end-of-line ($).

Mark Reed
  • 226
  • 1
  • 5