zsh-workers
 help / color / mirror / code / Atom feed
* replace-regex widget not replacing semicolons
@ 2013-06-11 12:49 Moritz Bunkus
  2013-06-11 17:07 ` Bart Schaefer
  0 siblings, 1 reply; 3+ messages in thread
From: Moritz Bunkus @ 2013-06-11 12:49 UTC (permalink / raw)
  To: zsh-workers

Hey,

I'm using replace-regex bound to ALT+r, and it usually works quite
well. Today I noticed that it doesn't replace semicolons, though. It
looks like an off-by-one error when removing the char from the buffer.
For example, when I enter

$ asd ; qwe

and replace ; by any single char (e.g. "+") then the line stays
exactly as it is.

However, if I try to replace it by two or more chars (e.g. "&&") then
one of the replaced chars is missing and the semicolon stays in its
place, like this:

$ asd &; qwe

How to reproduce:

chai-latte$ zsh --norcs
chai-latte% autoload regexp-replace
chai-latte% autoload replace-string
chai-latte% zle -N replace-regex replace-string
chai-latte% bindkey "^[r" replace-regex
chai-latte% asd ; qwe

Now hit ALT+r, enter ; and &&, see the output changed to:

chai-latte% asd &; qwe

Kind regards,
mosu


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: replace-regex widget not replacing semicolons
  2013-06-11 12:49 replace-regex widget not replacing semicolons Moritz Bunkus
@ 2013-06-11 17:07 ` Bart Schaefer
  2013-06-12  6:46   ` Moritz Bunkus
  0 siblings, 1 reply; 3+ messages in thread
From: Bart Schaefer @ 2013-06-11 17:07 UTC (permalink / raw)
  To: Moritz Bunkus, zsh-workers

On Jun 11,  2:49pm, Moritz Bunkus wrote:
}
} I'm using replace-regex bound to ALT+r, and it usually works quite
} well. Today I noticed that it doesn't replace semicolons, though. It
} looks like an off-by-one error when removing the char from the buffer.

It works for me with any replacement except those with "&" as the 2nd
or later character.  I think this is because "&" is a magic character
in regexp replacements, meaning a back-reference to the last string
that was matched?

There's a comment in replace-string-again:

    # The following horror is so that an & preceded by an even
    # number of backslashes is active, without stripping backslashes,
    # while preceded by an odd number of backslashes is inactive,
    # with one backslash being stripped.  A similar logic applies
    # to \digit.

("an even number of backslashes" includes zero of them).
 
What's happening with "&&" is that on entry to the regexp engine there
is no previous match, so "&" means itself.  Then the ";" is matched,
so now the second "&" means the matched part of the source string, and
becomes ";", and you end up with ";" =~ s/;/&&/ --> "&;".

Try with &\& or with p&q to see what I mean.  That the match pattern is
a semicolon doesn't matter.


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: replace-regex widget not replacing semicolons
  2013-06-11 17:07 ` Bart Schaefer
@ 2013-06-12  6:46   ` Moritz Bunkus
  0 siblings, 0 replies; 3+ messages in thread
From: Moritz Bunkus @ 2013-06-12  6:46 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: zsh-workers

Hey,

thanks for the thorough analysis. I haven't been aware that & is used
for representing the various matched parts, I'm used to $... (Perl) or
\... (the usualy Unix tools). Reading the documentation about
replace-string and friends I now see & being mentioned, so yes, it
does make sense. Sorry for not going there first.

Kind regards,
mosu


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2013-06-12  6:46 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-06-11 12:49 replace-regex widget not replacing semicolons Moritz Bunkus
2013-06-11 17:07 ` Bart Schaefer
2013-06-12  6:46   ` Moritz Bunkus

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).