all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* restore region after replace-string
@ 2011-01-14 22:57 Paul Madden
  0 siblings, 0 replies; 8+ messages in thread
From: Paul Madden @ 2011-01-14 22:57 UTC (permalink / raw)
  To: help-gnu-emacs

I'm not sure whether to ask the general or the specific question, so I'll ask both:

Generally, I'd like the region I've defined (transient-mark-mode on) to be
restored after a command like replace-string. I often want to run many
replacements on the same region, and don't want to keep recreating it. I thought
I'd mention the real goal, in case there's a better method than what follows.

Specifically, here's what I've tried:

(defun rs1 ()
  (interactive)
  (save-excursion (call-interactively 'replace-string)))

If I create a region and M-x rs1, the replacement works, point is restored, and
then I can use C-x C-x C-x C-x to get what I want: The same region highlighted
with point at its end.

But I don't want the extra keystrokes, so try to make the function do it for me:

(defun rs2 ()
  (interactive)
  (save-excursion (call-interactively 'replace-string))
  (exchange-point-and-mark)
  (exchange-point-and-mark))

But no region is highlighted. And if I do M-x replace-string after rs2, the
replacement occurs only below point in the buffer, so it seems no region is active.

Interestingly, though:

(defun rs3 ()
  (interactive)
  (save-excursion (call-interactively 'replace-string))
  (exchange-point-and-mark)
  (exchange-point-and-mark)
  (asdf))

After rs3, my region is highlighted with point at its end, and there's a
"definition is void" message (for the bogus (asdf) call) in the minibuffer. But
I can run replace-string now and it operates on the highlighted region.

So it seems like what I want is happening in rs3 (plus an unwanted error)... but
is undone when the function returns.

Can anybody shed any light on this, or point me in a better direction?

Incidentally, this is GNU Emacs 24.0.50.1, built from source, but I just tried
21.4.1 and it behaves the same.

thanks!
paul



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

* Re: restore region after replace-string
       [not found] <mailman.10.1295051790.18911.help-gnu-emacs@gnu.org>
@ 2011-01-15 13:23 ` LanX
  2011-01-15 20:07   ` Paul Madden
                     ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: LanX @ 2011-01-15 13:23 UTC (permalink / raw)
  To: help-gnu-emacs

> Can anybody shed any light on this, or point me in a better direction?

hmm I tried to find any switch in the documentation, but AFAIS it's an
integral feature of transient-mark-mode to disable the highlighting
after any changes in the buffer: 'Changing the buffer "deactivates"
the mark.'

C-h d mark.*mode will help you list all commands related to this
behavior.

I have two suggestions

- either explicitely mark the region by memorizing point and mark or
getting those positions from the mark-ring

- or use narrow-to-region and widen afterwords, like this you can use
anything you want on the region.

HTH
  Rolf


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

* Re: restore region after replace-string
  2011-01-15 13:23 ` restore region after replace-string LanX
@ 2011-01-15 20:07   ` Paul Madden
  2011-01-16 10:28   ` Le Wang
       [not found]   ` <mailman.15.1295181948.22773.help-gnu-emacs@gnu.org>
  2 siblings, 0 replies; 8+ messages in thread
From: Paul Madden @ 2011-01-15 20:07 UTC (permalink / raw)
  Cc: help-gnu-emacs

Hi Rolf,

> hmm I tried to find any switch in the documentation, but AFAIS it's an
> integral feature of transient-mark-mode to disable the highlighting
> after any changes in the buffer: 'Changing the buffer "deactivates"
> the mark.'

Definitely: I don't expect to stop the deactivation of the mark but only hope to
re-establish the region *after* replace-string has deactivated it.

I'm confused as to why C-x C-x C-x C-x works perfectly when I actually type the
keystrokes after my replace-string wrapper function returns, but the equivalent
two calls to (exchange-point-and-mark) inside my function fail. And having the
calls in a function isn't the problem, because if I

(defun zzz () (interactive) (exchange-point-and-mark) (exchange-point-and-mark))

and M-x zzz after calling my replace-string wrapper, it works just as well as
typing C-x C-x C-x C-x. It seems something else is happening inside

(defun rs ()
  (interactive)
  (save-excursion (call-interactively 'replace-string))
  (exchange-point-and-mark)
  (exchange-point-and-mark))

that kills the re-established region when the function returns.

And the region does seem to be re-established -- as mentioned in my previous
email, if I prevent a normal return from the function by adding a final bogus
call to a non-existent function in rs, I can see that the region has been
re-established and highlighted. But if rs returns normally, the new region gets
killed again. Maybe it's a bug.

> - either explicitely mark the region by memorizing point and mark or
> getting those positions from the mark-ring

It seems to me that point and mark are still valid, and the two calls to
(exchange-point-and-mark) are supposed, as you say, to explicitly mark the
region. But, to be more explicit, I also tried this:

(defun rs()
  (interactive)
  (point-to-register 1)
  (call-interactively 'replace-string)
  (exchange-point-and-mark)
  (push-mark (point) t t)
  (jump-to-register 1))

This behaves exactly the same way as the function above, and if I add a bogus
call at the end:

(defun rs()
  (interactive)
  (point-to-register 1)
  (call-interactively 'replace-string)
  (exchange-point-and-mark)
  (push-mark (point) t t)
  (jump-to-register 1)
  (asdf))

I again see the region re-established, but a message in the minibuffer about
void symbol asdf. In fact, if I could ignore the error message (hard to do),
this function does exactly what I want. But why?

> - or use narrow-to-region and widen afterwords, like this you can use
> anything you want on the region.

I tried that earlier, too. But I like the behavior of replace-string and don't
want to try to write a clone. Plus, I will want to similarly wrap other
functions like query-replace, replace-regexp, etc. and don't want to to
reimplement them as well.

I'm still trying things, and more ideas are always appreciated.

paul



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

* Re: restore region after replace-string
  2011-01-15 13:23 ` restore region after replace-string LanX
  2011-01-15 20:07   ` Paul Madden
@ 2011-01-16 10:28   ` Le Wang
  2011-01-16 17:08     ` Paul Madden
       [not found]   ` <mailman.15.1295181948.22773.help-gnu-emacs@gnu.org>
  2 siblings, 1 reply; 8+ messages in thread
From: Le Wang @ 2011-01-16 10:28 UTC (permalink / raw)
  To: LanX; +Cc: help-gnu-emacs

[-- Attachment #1: Type: text/plain, Size: 922 bytes --]

On Sat, Jan 15, 2011 at 9:23 PM, LanX <lanx.perl@googlemail.com> wrote:
> Can anybody shed any light on this, or point me in a better direction?

I had to solve this recently -- keeping the region active after a command
modifies the buffer.  The relevant documentation is here:
http://www.gnu.org/s/emacs/manual/html_node/elisp/The-Mark.html


Variable: *deactivate-mark*

If an editor command sets this variable non-nil, then the editor command
loop deactivates the mark after the command returns (if Transient Mark mode
is enabled). *All the primitives that change the buffer set deactivate-mark*,
to deactivate the mark when the command is finished.

To write Lisp code that modifies the buffer without causing deactivation of
the mark at the end of the command, bind deactivate-mark to nil around the
code that does the modification. For example:

          (let (deactivate-mark)

            (insert " "))



-- 
Le

[-- Attachment #2: Type: text/html, Size: 5937 bytes --]

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

* Re: restore region after replace-string
  2011-01-16 10:28   ` Le Wang
@ 2011-01-16 17:08     ` Paul Madden
  2011-01-17  2:22       ` Le Wang
  0 siblings, 1 reply; 8+ messages in thread
From: Paul Madden @ 2011-01-16 17:08 UTC (permalink / raw)
  Cc: help-gnu-emacs

Le,

Thank you! That was the key.

Here's the working function, in case it helps someone someday:

(defun rs ()
  (interactive)
  (let (deactivate-mark)
    (save-excursion (call interactively 'replace-string)))
  (exchange-point-and-mark)
  (exchange-point-and-mark))

paul

On 01/16/2011 03:28 AM, Le Wang wrote:

> I had to solve this recently -- keeping the region active after a command
> modifies the buffer.  The relevant documentation is
> here: http://www.gnu.org/s/emacs/manual/html_node/elisp/The-Mark.html
> 
> 
>     Variable: *deactivate-mark*
> 
>         If an editor command sets this variable non-|nil|, then the editor
>         command loop deactivates the mark after the command returns (if
>         Transient Mark mode is enabled). _All the primitives that change the
>         buffer set |deactivate-mark|_, to deactivate the mark when the command
>         is finished.
> 
>         To write Lisp code that modifies the buffer without causing deactivation
>         of the mark at the end of the command,
>         bind |deactivate-mark| to |nil| around the code that does the
>         modification. For example:
> 
>                   (let (deactivate-mark)
> 
>                     (insert " "))
> 
> 
> 
> -- 
> Le



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

* Re: restore region after replace-string
       [not found]   ` <mailman.15.1295181948.22773.help-gnu-emacs@gnu.org>
@ 2011-01-16 18:24     ` LanX
  0 siblings, 0 replies; 8+ messages in thread
From: LanX @ 2011-01-16 18:24 UTC (permalink / raw)
  To: help-gnu-emacs

Hi Paul

I dunno why your approaches aren't working, and you seem to be much
more proficient with elisp than me. :)

Anyway Le's suggestion works flawlessly for me:

(defun rs ()
  (interactive)
  (let (deactivate-mark)
    (save-excursion (call-interactively 'replace-string))
    (exchange-point-and-mark)
    (exchange-point-and-mark))
)

HTH
  Rolf


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

* Re: restore region after replace-string
  2011-01-16 17:08     ` Paul Madden
@ 2011-01-17  2:22       ` Le Wang
  2011-01-17  2:38         ` Paul Madden
  0 siblings, 1 reply; 8+ messages in thread
From: Le Wang @ 2011-01-17  2:22 UTC (permalink / raw)
  To: Paul Madden; +Cc: help-gnu-emacs

[-- Attachment #1: Type: text/plain, Size: 543 bytes --]

On Mon, Jan 17, 2011 at 1:08 AM, Paul Madden <Paul.A.Madden@noaa.gov> wrote:

> (defun rs ()
>  (interactive)
>  (let (deactivate-mark)
>    (save-excursion (call interactively 'replace-string)))
>  (exchange-point-and-mark)
>  (exchange-point-and-mark))
>
>
You don't need the exchange-point-and-mark calls.  As a part of the Emacs
commandloop, deactivate-mark is checked after executing your command, `rs'.
 As long as you prevent your buffer modification code from setting
`deactivate-mark' to not-nil, the region should be active.

-- 
Le

[-- Attachment #2: Type: text/html, Size: 866 bytes --]

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

* Re: restore region after replace-string
  2011-01-17  2:22       ` Le Wang
@ 2011-01-17  2:38         ` Paul Madden
  0 siblings, 0 replies; 8+ messages in thread
From: Paul Madden @ 2011-01-17  2:38 UTC (permalink / raw)
  Cc: help-gnu-emacs

You're right -- that's even better. Thanks again.

paul

On 01/16/2011 07:22 PM, Le Wang wrote:
> On Mon, Jan 17, 2011 at 1:08 AM, Paul Madden <Paul.A.Madden@noaa.gov
> <mailto:Paul.A.Madden@noaa.gov>> wrote:
> 
>     (defun rs ()
>      (interactive)
>      (let (deactivate-mark)
>        (save-excursion (call interactively 'replace-string)))
>      (exchange-point-and-mark)
>      (exchange-point-and-mark))
> 
> 
> You don't need the exchange-point-and-mark calls.  As a part of the Emacs
> commandloop, deactivate-mark is checked after executing your command, `rs'.  As
> long as you prevent your buffer modification code from setting `deactivate-mark'
> to not-nil, the region should be active.
> 
> -- 
> Le



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

end of thread, other threads:[~2011-01-17  2:38 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <mailman.10.1295051790.18911.help-gnu-emacs@gnu.org>
2011-01-15 13:23 ` restore region after replace-string LanX
2011-01-15 20:07   ` Paul Madden
2011-01-16 10:28   ` Le Wang
2011-01-16 17:08     ` Paul Madden
2011-01-17  2:22       ` Le Wang
2011-01-17  2:38         ` Paul Madden
     [not found]   ` <mailman.15.1295181948.22773.help-gnu-emacs@gnu.org>
2011-01-16 18:24     ` LanX
2011-01-14 22:57 Paul Madden

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.