There's a problem I've encountered with Emacs for many years. I
never reported it because I've been running Emacs 21.3 under
Windows, and I figured that Emacs users on Windows are probably a
very small percentage of Emacs users, and that 21.3 is so old that
it nobody would be interested in debugging the problem.
But then I encountered the same problem with Emacs 23.2.1 running
under Linux. And a few days ago I finally installed Windows Emacs
23.4.1, and it's got the same problem.
The problem: the replace commands, M-x replace-string and
M-x replace-regexp, sometimes work and sometimes don't.
When it doesn't work, it often will work if I retype exactly the
same command a few times.
My reaction when I first encountered the problem was that I must
have mistyped the command the first time. But I've encountered it
for so many years that whenever it fails to work the first time,
it's become habit for me to be extremely careful in my typing the
second and subsequent times, and it often fails on those tries too,
but eventually succeeds.
I particularly notice it when I'm defining a macro [ delimited by
C-x ( and C-x ) ]. And frequently I have the buffer narrowed to a
small subset of text that I want to operate on. But I don't know
for certain that defining a macro or having the buffer narrowed are
what cause the problem to manifest.
I now have a concrete example of this that proves that it's not due
to my mistyping. There's a point in the macro where the buffer has
been narrowed to a portion that contains a symbol in CamelCase.
Note: In case
you're unfamiliar with CamelCase, it's a convention for variable
names originally popularized by the X Window System. Earlier
conventions for C and C++ used "_" as a word delimiter within
variable names. Lisp used "-" instead of "_". CamelCase,
so-called because the capital letters in the middle of the word
form humps like those on a camel's back, uses capital letters to
indicate the beginning of a new word. So, the C-style variable
name find_char_in_string, or Lisp-style variable name
find-char-in-string, in CamelCase is findCharInString.
The purpose of this part of the macro is to turn CamelCase into
space-separated words.
M-< ;; Go to beginning of
narrowed buffer
M-x replace-regexp RET
[A-Z] RET ;; Find any capital letter
C-q SPC \& RET
;; Replace it with a space followed by itself
M-< ;; Go to beginning of narrowed
buffer
C-d ;; Delete the unwanted space before
the first letter
So, if the narrowed portion of the buffer contains:
"JohnJacobJingleheimerschmidt"
after running this portion of the macro, it should contain:
"John Jacob Jingleheimerschmidt"
Instead, when run in Emacs 23, the result is:
"ohnJacobJingleheimerschmidt"
which is exactly what you'd expect if the M-x replace-regexp
failed to do the replacement that it should have. But since I know
that sometimes a replace command works the second time after failing
to work the first time, I modified that portion of the macro to do
the replace twice:
M-< ;; Go to beginning of
narrowed buffer
M-x replace-regexp RET
[A-Z] RET ;; Find any capital letter
C-q SPC \& RET
;; Replace it with a space followed by itself
M-< ;; Go to beginning of narrowed
buffer
M-x replace-regexp RET
[A-Z] RET ;; Find any capital letter
C-q SPC \& RET
;; Replace it with a space followed by itself
M-< ;; Go to beginning of narrowed
buffer
C-d ;; Delete the unwanted space before
the first letter
Now, if the replace were working the first time, applying it again
would produce the undesired result:
" John Jacob Jingleheimerschmidt"
Instead, it produces:
"John Jacob Jingleheimerschmidt"
Does anybody here have any idea what's going wrong here?
Mark Rosenthal
mbr@arlsoft.com
P.S. - One further clue: In the older version of Emacs (21.3) I've
noticed that at those times when the replace fails to work, if I
repeat the replace command with C-x ESC ESC, the minibuffer shows:
(replace-regexp "[A-Z]" " \\&" nil sss eee)
where sss and eee are integers that are supposed to indicate the
beginning and end characters of the region to operate on, but when
the replace has failed, sss and eee specify a small subset of the
region.