help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: How to return to the position from where I did tags-query-replace?


From: aklaing
Subject: Re: How to return to the position from where I did tags-query-replace?
Date: Sun, 4 Feb 2018 12:29:25 -0800 (PST)
User-agent: G2/1.0

Another minor note if anyone wants to use this: as suggested by Emanuel, you 
will need to use these to put it in place (or remove it):

(advice-add 'tags-query-replace :around #'do-tags-query-replace-return)
;; (advice-remove 'tags-query-replace #'do-tags-query-replace-return)

On Sunday, February 4, 2018 at 3:14:39 PM UTC-5, akl...@gmail.com wrote:
> 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 via email to

[Prev in Thread] Current Thread [Next in Thread]