all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: aklaing@gmail.com
To: help-gnu-emacs@gnu.org
Subject: Re: How to return to the position from where I did tags-query-replace?
Date: Sun, 4 Feb 2018 12:14:36 -0800 (PST)	[thread overview]
Message-ID: <34aa48a3-00b7-4adc-a103-474738a6cf57@googlegroups.com> (raw)
In-Reply-To: <86mv0pweel.fsf@zoho.com>

Thanks Emanuel for taking a look at this.  Your solution works correctly for your test case (moving to a random buffer and location) but not as-written for tags-query-replace, which has some peculiarities (I just realized).

Looking at the code, the tags-query-replace function uses a function called
user-error for flow control.  Deep in the logic, if it realizes that it has finished the job normally, it calls user-error, which is somewhat similar to throwing an exception deep in the call stack.  Because this unwinds the stack and discards it, the part of the code following (apply fun args) never gets evaluated.  This probably also explains why my two initial attempts do not work.

One hacky solution (based on your approach) is to do something similar to putting a try/catch around the call to (apply fun args), as follows:

(defun do-tags-query-replace-return (fun &rest args)
  (let ((tmp-point  (point)) 
        (tmp-buffer (current-buffer)))
    (message "DWR Before: %d %s %s" tmp-point tmp-buffer args)
    (condition-case tmp-err
	(apply fun args)
      (user-error
       (let ((err-message (cadr tmp-err)))
	 (if (string= err-message "All files processed")
	     (message "DWR Trapped: %s" err-message)
	   (signal (car tmp-err) (cdr tmp-err))))))
    (message "DWR After: %d %s %s" tmp-point tmp-buffer args)
    (when (bufferp tmp-buffer)
      (switch-to-buffer tmp-buffer)
      (goto-char tmp-point)
      nil)))

Notes: this is similar to putting a try/catch around the
(apply fun args).  I say it is (only) similar because elisp has a notion of try/catch which is different from its own notion of error-handling, though
there are similarities.

I like your approach better than my first two attempts because it does not require an external package like breadcrumb.  Though (I believe) registers are native in emacs, it is better to avoid using persistent state for something that should really be on the execution stack.

It should be noted that this solution only works for tags-query-replace, because it only traps one very specific type of error, which is the one tags-query-replace "throws" when it completes normally.  If tags-query-replace exits for any other real error, this will fail -- in the sense that it will not return to where it was before it started.  And I think that is a good thing.

One thing that is still not good about this solution is that if etags.el changes the string that it uses to indicate completion ("All files processed"), this solution will stop working.  That is too fragile.

In the long term, it would probably be better for etags.el to not use user-error to indicate normal completion, but that is more elisp than I want to do right now.  It requires changes in more than one place.  If the/an author of etags.el reads this and you have some time, maybe you can please take a look?

If anyone wants to use the hacky solution above, you might as well remove the DWR message calls.

Thanks again for your help, it pushed me to spend more time on it and learn a bit more elisp than I already knew.

Thanks,

On Saturday, February 3, 2018 at 11:46:13 PM UTC-5, Emanuel Berg wrote:
> Emanuel Berg wrote:
> 
> > (goto-char (point))
> 
> He he, good one! That should be
> 
>     (goto-char point)
> 
> Any further edits will be in the source
> file [1] only. Modern society does not allow
> this inefficiency.
> 
> [1] http://user.it.uu.se/~embe8573/emacs-init/my-random.el
> 
> -- 
> underground experts united
> http://user.it.uu.se/~embe8573



  reply	other threads:[~2018-02-04 20:14 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-09-05 18:33 How to return to the position from where I did tags-query-replace? Yevgeniy Makarov
2007-09-05 21:41 ` Eric Hanchrow
     [not found] ` <mailman.388.1189029337.18990.help-gnu-emacs@gnu.org>
2018-02-03 22:27   ` Ambrose Laing
2018-02-04  3:28     ` Emanuel Berg
2018-02-04  4:30       ` Emanuel Berg
2018-02-04  4:34         ` Emanuel Berg
2018-02-04  4:46         ` Emanuel Berg
2018-02-04 20:14           ` aklaing [this message]
2018-02-04 20:25             ` Emanuel Berg
2018-02-04 20:36               ` Emanuel Berg
2018-02-04 20:37               ` aklaing
2018-02-04 20:41                 ` Emanuel Berg
2018-02-04 20:52                   ` aklaing
2018-02-04 21:02                     ` Emanuel Berg
2018-02-04 20:29             ` aklaing
2018-02-04 20:38               ` Emanuel Berg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=34aa48a3-00b7-4adc-a103-474738a6cf57@googlegroups.com \
    --to=aklaing@gmail.com \
    --cc=help-gnu-emacs@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.