:s/\n/... fails on last line of text

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

:s/\n/... fails on last line of text

Bill McCarthy
Hello Vim List,

I noticed the following example in change.txt (:help
sub-replace-expression):

  :s@\n@\="\r" . expand("$HOME") . "\r"@

It fails on the last line of a file because the \n isn't
found - even though there really is an eol byte (unix or
max) or byte pair (dos).  Why?

I have always using $ in these situations, so I haven't
noticed this before now.

BTW, that example fails for Windows or any other OS that
uses back slashes in file paths.  A more general solution
would be:

  :s@$@\="\r" . substitute(expand("$HOME"),'\\','\\\\',"g") . "\r"@

--
Best regards,
Bill


Reply | Threaded
Open this post in threaded view
|

Re: :s/\n/... fails on last line of text

A.J.Mechelynck
----- Original Message -----
From: "Bill McCarthy" <[hidden email]>
To: "Vim List" <[hidden email]>
Sent: Sunday, August 14, 2005 5:45 AM
Subject: :s/\n/... fails on last line of text


> Hello Vim List,
>
> I noticed the following example in change.txt (:help
> sub-replace-expression):
>
>  :s@\n@\="\r" . expand("$HOME") . "\r"@
>
> It fails on the last line of a file because the \n isn't
> found - even though there really is an eol byte (unix or
> max) or byte pair (dos).  Why?
>
> I have always using $ in these situations, so I haven't
> noticed this before now.
>
> BTW, that example fails for Windows or any other OS that
> uses back slashes in file paths.  A more general solution
> would be:
>
>  :s@$@\="\r" . substitute(expand("$HOME"),'\\','\\\\',"g") . "\r"@

Wouldn't the above add an empty line after the directory? ( /$/, unlike
/\n/, is a zero-length match)

I suggest

    :s/$/\="\r" . escape($HOME,'\')

or, of you want, for instance, to expand "C:\DOCUME~1\Bill" into
"C:\Documents and Settings\Bill" (which the above doesn't do) then

    :s/$/\="r" . escape(expand($HOME),'\')

>
> --
> Best regards,
> Bill

Best regards,
Tony.


Reply | Threaded
Open this post in threaded view
|

Re: :s/\n/... fails on last line of text

Bill McCarthy
On Sun 14-Aug-05 12:56am -0500, Tony Mechelynck wrote:


> From: "Bill McCarthy" <[hidden email]>
> To: "Vim List" <[hidden email]>
> Sent: Sunday, August 14, 2005 5:45 AM
> Subject: :s/\n/... fails on last line of text
>
>
>> Hello Vim List,
>>
>> I noticed the following example in change.txt (:help
>> sub-replace-expression):
>>
>>  :s@\n@\="\r" . expand("$HOME") . "\r"@
>>
>> It fails on the last line of a file because the \n isn't
>> found - even though there really is an eol byte (unix or
>> max) or byte pair (dos).  Why?
>>
>> I have always using $ in these situations, so I haven't
>> noticed this before now.
>>
>> BTW, that example fails for Windows or any other OS that
>> uses back slashes in file paths.  A more general solution
>> would be:
>>
>>  :s@$@\="\r" . substitute(expand("$HOME"),'\\','\\\\',"g") . "\r"@
>
> Wouldn't the above add an empty line after the directory? ( /$/, unlike
> /\n/, is a zero-length match)

Yes it would - I missed that.  Your suggestion of using
escape() instead of substitute() is an excellent one!

But the question remains as to why the search for `\n`
always appears to fail on the last line.

--
Best regards,
Bill


Reply | Threaded
Open this post in threaded view
|

Re: :s/\n/... fails on last line of text

A.J.Mechelynck
----- Original Message -----
From: "Bill McCarthy" <[hidden email]>
To: "Tony Mechelynck" <[hidden email]>
Cc: "Vim List" <[hidden email]>
Sent: Sunday, August 14, 2005 8:32 AM
Subject: Re: :s/\n/... fails on last line of text
[...]

> But the question remains as to why the search for `\n`
> always appears to fail on the last line.
>
> --
> Best regards,
> Bill

I'm not sure but I guess it's due to how the data is internally represented
by Vim. When reading a file, it takes note of whether there is an EOL on the
last line and stores the result in the 'eol' option. When writing, it always
puts an ending EOL unless 'binary' and 'noeol' are both set. Not sure if the
internal representation is all ASCIIZ strings (one per line) or if the last
one has something special.

Best regards,
Tony.


Reply | Threaded
Open this post in threaded view
|

Re: :s/\n/... fails on last line of text

Bram Moolenaar
In reply to this post by Bill McCarthy

Bill McCarthy wrote:

> I noticed the following example in change.txt (:help
> sub-replace-expression):
>
>   :s@\n@\="\r" . expand("$HOME") . "\r"@
>
> It fails on the last line of a file because the \n isn't
> found - even though there really is an eol byte (unix or
> max) or byte pair (dos).  Why?
>
> I have always using $ in these situations, so I haven't
> noticed this before now.

This was done to make the implementation easier.  Advancing the input
after matching that "\n" means pointing beyond the last line.  But it's
possible to check for this situation.  I'll look into it...  It's
possible, but there might be situations where you get an error for the
cursor being past the end of the file.  I found one situation so far,
there may be others hiding...

--
Just remember...if the world didn't suck, we'd all fall off.

 /// Bram Moolenaar -- [hidden email] -- http://www.Moolenaar.net   \\\
///        Sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\              Project leader for A-A-P -- http://www.A-A-P.org        ///
 \\\     Buy LOTR 3 and help AIDS victims -- http://ICCF.nl/lotr.html   ///
Reply | Threaded
Open this post in threaded view
|

Re: :s/\n/... fails on last line of text

Bill McCarthy
On Sun 14-Aug-05 7:23am -0500, Bram Moolenaar wrote:

> Bill McCarthy wrote:

>> I noticed the following example in change.txt (:help
>> sub-replace-expression):
>>
>>   :s@\n@\="\r" . expand("$HOME") . "\r"@
>>
>> It fails on the last line of a file because the \n isn't
>> found - even though there really is an eol byte (unix or
>> max) or byte pair (dos).  Why?
>>
>> I have always using $ in these situations, so I haven't
>> noticed this before now.

> This was done to make the implementation easier.  Advancing the input
> after matching that "\n" means pointing beyond the last line.  But it's
> possible to check for this situation.  I'll look into it...  It's
> possible, but there might be situations where you get an error for the
> cursor being past the end of the file.  I found one situation so far,
> there may be others hiding...

Now works nicely in build 130 of 7 alpha!

--
Best regards,
Bill