I am writing a function to reformat a visual selection:
function! FormatText() range " Calling this function has ended visual mode, so it must be started " again before the selection can be yanked into the unnamed register. normal! gvy let selection = @" echomsg 'Z'.selection.'Z' let cmd = 'sort' let output = system(cmd, selection) echomsg 'X'.output.'X' silent exe "'<,'>s/.*/" . output . "/" endfunction
The examination of @" value reveals that spaces and new lines are randomly replaced by ^@.
Any idea why this is happening and how to handle this? Is there a better approach to get the context of the visual selection?
UPDATE: After the feedback I know now that ^@ is a new line replacement. I also provided the actual function. I have to withdraw the statement about spaces, only new lines are replaced by ^@. The spaces were replaced by external program because it could not handle 0 bytes. To eliminate the external program effect I am using the sort to illustrate what's happening.
open a file with the following content: z line a line
visually select both line and trigger the function by the following mapping: vnoremap f :call FormatText()
echomsg output (works as expected) Zzline^@a line^@Z Xaline^@z line^@X
The selection in file changed to: aline^@z line^@ aline^@z line^@
I have more questions now.
a) Why is the selection contents doubled? Is this approach wrong:
silent exe "'<,'>s/.*/" . output . "/"
I tried \%V
silent exe "'<,'>s/\\%V.*\\%V/" . output . "/"
but the result is the same.
b) Is there a way to get the visual selection as it is, without transformation?
c) How does built-in gq with 'formatexpr' works? Does it convert ^@ to new lines first? Would it be awkward to do it for all type of file formats?