0

I have a vim register that contains a string. I need to step through each character in the string, and process each one individually.

My problem is that given a character pulled from the string, I am unable to tell the difference between a nul 0x00 character and a newline 0x0a.

Because the register is specified by v:register, I cannot (as far as I know) access the register directly in a script in a way that would allow me to index into it (I'd be very happy to be corrected) and so I have to first copy/ref the register with let l:string = getreg(v:register) and then operate on l:string.

I have tried the following;-

  1. char2nr(l:string[x]) - always returns a nul character as 0x0a
  2. match(l:string[x], '[\x0]') - Matches 0x00 and 0x0a characters!
  3. match(l:string[x], '\%x00') - Matches 0x00 and 0x0a characters! (though I would swear that this actually worked for me at one point - maybe I'm losing the plot?)
  4. I have even tried pasting the character to a buffer with the hope of using the g8 mapping to read back its value (ie, exe "normal! r".l:string[x]."\<esc>") but it pasted a newline 0x0a
  5. A couple of other things which frankly I've forgotten now

Does anyone have any idea how I may accomplish this? The frustrating thing is vim handles nul characters perfectly fine when they appear in a buffer (and it can visually select and yank them, and paste them again with no issues). But trying to deal with nul contained in a string or register seems to be broken.

Just for some background, the docs for char2nr() states that

"NUL character in the file is specified with nr2char(10), because NULs are represented with newline characters. nr2char(0) is a real NUL and terminates the string, thus results in an empty string"

This seems to be somewhat inaccurate (or not the whole story) because nul chars in a file/buffer are handled correctly. And a register that contains a nul can still be pasted into a document and it's correctly pasted as nul. So SOMETHING is making the distinction between nul and newline

Any help would be greatly appreciated

5
  • In many programming languages, a null character/byte is used to terminate a sting. Hence a (null-terminated) sting cannot possibly contain embedded null characters (since the very first null would be treated as the end of the string). You would need to use a byte or character array (rather than a string construct) to process null characters within text. BTW the ASCII mnemonic for the null character is NUL; otherwise "null" is spelled with two 'l's.
    – sawdust
    Feb 27, 2023 at 1:17
  • Why do you even have NULs embedded in your text strings? Perhaps you can preprocess the file with a binary (aka hex) editor, and replace each NUL with some other ASCII control character?
    – sawdust
    Feb 27, 2023 at 1:29
  • @sawdust - I know, but that's an implementation detail and not something I would expect to be exposed to the user of an editor (at least I wouldn't do that!). But my point remains that SOME parts of vim handle nul (NUL :-)) characters with no issues
    – Rich88
    Feb 27, 2023 at 13:38
  • @sawdust - I have written a hex editor in vim, using the xxd utility. I have managed to get around all of vim's other 'issues' regarding how it handles NUL and newlines. This one issue is proving to be rather awkward though. I CAN get around it but it will be a lot more work and not as efficient
    – Rich88
    Feb 27, 2023 at 13:42
  • @Peregrino69 - Sorry about that. Point noted
    – Rich88
    Feb 27, 2023 at 13:43

0

You must log in to answer this question.

Browse other questions tagged .