[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: save-excursion again
From: |
Stephen J. Turnbull |
Subject: |
Re: save-excursion again |
Date: |
Sat, 19 Jun 2010 23:50:05 +0900 |
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.
- save-excursion again, Uday S Reddy, 2010/06/18
- Re: save-excursion again, Stefan Monnier, 2010/06/18
- Re: save-excursion again, David Kastrup, 2010/06/18
- Re: save-excursion again, Uday S Reddy, 2010/06/18
- Re: save-excursion again, Stefan Monnier, 2010/06/18
- Re: save-excursion again,
Stephen J. Turnbull <=
- Re: save-excursion again, Lennart Borgman, 2010/06/19
- Re: save-excursion again, Lennart Borgman, 2010/06/19
- Re: save-excursion again, Stephen J. Turnbull, 2010/06/19
- Re: save-excursion again, Lennart Borgman, 2010/06/19
- Re: save-excursion again, Stefan Monnier, 2010/06/25
- Re: save-excursion again, Stephen J. Turnbull, 2010/06/25
- Re: save-excursion again, Stefan Monnier, 2010/06/30
- Re: save-excursion again, Uday S Reddy, 2010/06/26
- Re: save-excursion again, Stefan Monnier, 2010/06/30
- Re: save-excursion again, Lennart Borgman, 2010/06/30