From: "Stephen J. Turnbull" <turnbull@sk.tsukuba.ac.jp>
To: Uday S Reddy <u.s.reddy@cs.bham.ac.uk>
Cc: Stefan Monnier <monnier@iro.umontreal.ca>, emacs-devel@gnu.org
Subject: Re: save-excursion again
Date: Sat, 19 Jun 2010 23:50:05 +0900 [thread overview]
Message-ID: <87pqzncc0y.fsf@uwakimon.sk.tsukuba.ac.jp> (raw)
In-Reply-To: <19483.43525.253000.115910@gargle.gargle.HOWL>
Uday S Reddy writes:
> When I first got involved with VM, there were a host of problems that
> were called "jumping cursor" issues. You do something and the cursor
> ends up at a different place.
The point is that if
;; current buffer is "bar"
(save-excursion
(set-buffer "foo")
(frob-current-buffer))
protects "bar" from jumping cursor, then `frob-current-buffer' must
switch back to "bar" and move the cursor at some point.
If your code is doing that kind of thing, then you end up with
> In fact, I would have rather liked a compiler that asked, do you
> really want to do set-buffer without a save-excursion first?
But that's *not good enough*. Suppose a new feature requires this
code:
;; current buffer is "bar"
(frob-current-buffer)
Now you're going to see jumping cursor without a set-buffer to warn
you. The obvious try is
;; current buffer is "bar"
(save-excursion (frob-current-buffer))
but since `frob-current-buffer' is used in situations where jumping
cursor is bad, why not
(fset 'frob-current-buffer-internal (symbol-function 'frob-current-buffer))
(defun frob-current-buffer (&rest args)
(save-excursion (apply #'frob-current-buffer-internal args)))
and save yourself future aggravation by using `frob-current-buffer'
except when point motion is the intent?
> That is, set-buffer without save-excursion is dangerous, because it
> might lead to the "jumping cursor" problem.
No. It's the code *after* the set-buffer that's dangerous, not the
set-buffer. That fact that you consider set-buffer per se dangerous
is a strong suggestion that your program is rotten with code that does
set-buffer and then moves point without a save-excursion.
> I will assume you are joking. But, why bother with any of this at
> all? What is wrong with the original code in the first place?
Nothing, assuming that the whole project is already using functions
that have nasty side-effects of moving point in buffers they aren't
called from. In that case it might be cheaper for you to wrap every
set-buffer and following code in a save-excursion, but it's not 100%
reliable. And it's *much* better to write new code to avoid side
effects except in functions designed to produce side effects.
It's true that using the set-buffer heuristic you'll probably catch
*most* such issues, because a lot of the functions of the form
(defun find-something (quux)
(set-buffer "bar")
;; I should have put a save-excursion *here* but didn't. Oops.
(if (search-forward quux nil t)
(extract-info-from-line-in-bar)
(error "No quux here, boss!")))
are mostly called from other buffers (in a context like VM, if you're
in "bar", you're probably already on the appropriate line, so you call
`extract-info-from-line-in-bar' directly, not via `find-something').
But you can't guarantee that.
next prev parent reply other threads:[~2010-06-19 14:50 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-06-18 7:42 save-excursion again Uday S Reddy
2010-06-18 13:51 ` Stefan Monnier
2010-06-18 14:02 ` David Kastrup
2010-06-18 15:29 ` Stefan Monnier
2010-06-18 17:16 ` Uday S Reddy
2010-06-18 18:37 ` Stefan Monnier
2010-06-19 14:50 ` Stephen J. Turnbull [this message]
2010-06-19 14:56 ` Lennart Borgman
2010-06-19 14:58 ` Lennart Borgman
2010-06-19 17:23 ` Stephen J. Turnbull
2010-06-19 17:30 ` Lennart Borgman
2010-06-25 21:20 ` Stefan Monnier
2010-06-26 0:40 ` Stephen J. Turnbull
2010-07-01 0:26 ` Stefan Monnier
2010-07-01 4:34 ` Stephen J. Turnbull
2010-07-04 17:07 ` Stefan Monnier
2010-06-26 11:03 ` Uday S Reddy
2010-07-01 0:30 ` Stefan Monnier
2010-07-01 1:54 ` Lennart Borgman
2010-07-04 17:08 ` Stefan Monnier
2010-06-19 16:22 ` Uday S Reddy
2010-06-18 15:04 ` Davis Herring
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=87pqzncc0y.fsf@uwakimon.sk.tsukuba.ac.jp \
--to=turnbull@sk.tsukuba.ac.jp \
--cc=emacs-devel@gnu.org \
--cc=monnier@iro.umontreal.ca \
--cc=u.s.reddy@cs.bham.ac.uk \
/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.