* (save-excursion (other-window 1)) leaves me in the other window @ 2010-03-05 20:33 Sean McAfee 2010-03-05 22:21 ` Joe Fineman 2010-03-07 6:55 ` Tim X 0 siblings, 2 replies; 9+ messages in thread From: Sean McAfee @ 2010-03-05 20:33 UTC (permalink / raw) To: help-gnu-emacs A native reimplementation of scroll-other-window doesn't work as I'd expect: (save-excursion (other-window 1) (scroll-up)) The problem is that the current window isn't restored, which surprised me considerably. Why doesn't this work, and how would I write a function to go do some stuff in the other window and then come back? ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: (save-excursion (other-window 1)) leaves me in the other window 2010-03-05 20:33 (save-excursion (other-window 1)) leaves me in the other window Sean McAfee @ 2010-03-05 22:21 ` Joe Fineman 2010-03-07 6:55 ` Tim X 1 sibling, 0 replies; 9+ messages in thread From: Joe Fineman @ 2010-03-05 22:21 UTC (permalink / raw) To: help-gnu-emacs Sean McAfee <eefacm@gmail.com> writes: > A native reimplementation of scroll-other-window doesn't work as I'd > expect: > > (save-excursion > (other-window 1) > (scroll-up)) > > The problem is that the current window isn't restored, which > surprised me considerably. Why doesn't this work, and how would I > write a function to go do some stuff in the other window and then > come back? I believe save-excursion should be save-window-excursion. -- --- Joe Fineman joe_f@verizon.net ||: Everything you do costs money, dissipates heat, and makes :|| ||: crumbs. :|| ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: (save-excursion (other-window 1)) leaves me in the other window 2010-03-05 20:33 (save-excursion (other-window 1)) leaves me in the other window Sean McAfee 2010-03-05 22:21 ` Joe Fineman @ 2010-03-07 6:55 ` Tim X 2010-03-08 3:09 ` Sean McAfee 1 sibling, 1 reply; 9+ messages in thread From: Tim X @ 2010-03-07 6:55 UTC (permalink / raw) To: help-gnu-emacs Sean McAfee <eefacm@gmail.com> writes: > A native reimplementation of scroll-other-window doesn't work as I'd > expect: > > (save-excursion > (other-window 1) > (scroll-up)) > > The problem is that the current window isn't restored, which surprised > me considerably. Why doesn't this work, and how would I write a > function to go do some stuff in the other window and then come back? As emacs already has the command to scroll the other window, I'm assuming your example is a simplification of what you really want to do. However, if you were writing your own version as a learning exercise, the best soruce of help is to look at the source for scroll-other-window. That will probably give you more valuable insight than any of the responses you will get here and you can be fairly confident that the information you get is correct! I'd highly recommend reading the Introduction to Emacs Lisp book that comes with emacs. You will also benefit by doing a high level scan and skim reading of the elisp reference manual. A couple of things to consider. Windows are really the interface for us humans and not necessary the right abstraction to work at if you just want to do non-interactive manipulation of data using elisp. Have a look at buffers. This is where you will generally focus. Often the general approach is 1. Save important data 2. switch to a buffer 3. Do stuff in that buffer 4. Possibly make that buffer *visible* by showing it or just return to wehre you were. The point is, you don't have to do stuff only in a visible buffer. More often than not, you will do stuff in the buffer and either return to where you were, never making what you did visible right then or maybe you will make the work you have done visible once you hve finished doing it. You usually only make the buffer visible prior to doing som eprocessing if you need that to be interactive and the user needs to see what your doing or you are making interface changes, such as scrolling. Also, in addition to save-excursion, have a look at unwind-protect, save-match-data, save-window-excursion, with-current-buffer, with-temp-buffer, set-buffer, current-buffer etc I would also be careful about using constructs like (other-window 1) in elisp code - you don't know what that other window is as it will be different depending on what you are doing. Usually best to work with buffer names when you can. Tim -- tcross (at) rapttech dot com dot au ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: (save-excursion (other-window 1)) leaves me in the other window 2010-03-07 6:55 ` Tim X @ 2010-03-08 3:09 ` Sean McAfee 2010-03-08 7:26 ` Tim X 0 siblings, 1 reply; 9+ messages in thread From: Sean McAfee @ 2010-03-08 3:09 UTC (permalink / raw) To: help-gnu-emacs Tim X <timx@nospam.dev.null> writes: > Sean McAfee <eefacm@gmail.com> writes: >> A native reimplementation of scroll-other-window doesn't work as I'd >> expect: >> >> (save-excursion >> (other-window 1) >> (scroll-up)) >> >> The problem is that the current window isn't restored, which surprised >> me considerably. Why doesn't this work, and how would I write a >> function to go do some stuff in the other window and then come back? > > As emacs already has the command to scroll the other window, I'm > assuming your example is a simplification of what you really want to do. True. The situation is this: I have a frame, split horizontally into two windows. One window shows text that came from an OCR process; the other window, in image-mode, shows the (large) image that was the input to that OCR process. What I want to do is work in the text window, shifting the image in the other window around as I check it against the text. I assumed I could do something like this: (defmacro in-other-window (&rest body) `(save-excursion (other-window 1) ,@body)) And then: (global-set-key [(shift down)] (lambda () (interactive) (in-other-window (image-next-line)))) ...and similarly for the other three directions. Although the documentation for save-excursion says that it saves and restores the current buffer, it doesn't in this case. I still don't really know why. I tried using save-window-excursion instead as Joe Fineman suggested, but while that worked for image-next-line and image-previous-line, it doesn't for image-forward-hscroll, which I need for scrolling horizontally. I guess the horizontal scroll amount is something that's saved and restored by save-window-excursion. So I finally settled on this: (defmacro in-other-window (&rest body) `(progn (other-window 1) (unwind-protect (progn ,@body) (other-window -1)))) I just have to be careful not to alter the window configuration from within in-other-window. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: (save-excursion (other-window 1)) leaves me in the other window 2010-03-08 3:09 ` Sean McAfee @ 2010-03-08 7:26 ` Tim X 2010-03-08 16:55 ` Sean McAfee 0 siblings, 1 reply; 9+ messages in thread From: Tim X @ 2010-03-08 7:26 UTC (permalink / raw) To: help-gnu-emacs Sean McAfee <eefacm@gmail.com> writes: > Tim X <timx@nospam.dev.null> writes: > >> Sean McAfee <eefacm@gmail.com> writes: >>> A native reimplementation of scroll-other-window doesn't work as I'd >>> expect: >>> >>> (save-excursion >>> (other-window 1) >>> (scroll-up)) >>> >>> The problem is that the current window isn't restored, which surprised >>> me considerably. Why doesn't this work, and how would I write a >>> function to go do some stuff in the other window and then come back? >> >> As emacs already has the command to scroll the other window, I'm >> assuming your example is a simplification of what you really want to do. > > True. The situation is this: > > I have a frame, split horizontally into two windows. One window shows > text that came from an OCR process; the other window, in image-mode, > shows the (large) image that was the input to that OCR process. What I > want to do is work in the text window, shifting the image in the other > window around as I check it against the text. I assumed I could do > something like this: > > (defmacro in-other-window (&rest body) > `(save-excursion (other-window 1) ,@body)) > > And then: > > (global-set-key [(shift down)] > (lambda () (interactive) (in-other-window (image-next-line)))) > > ...and similarly for the other three directions. > > Although the documentation for save-excursion says that it saves and > restores the current buffer, it doesn't in this case. I still don't > really know why. I tried using save-window-excursion instead as Joe > Fineman suggested, but while that worked for image-next-line and > image-previous-line, it doesn't for image-forward-hscroll, which I need > for scrolling horizontally. I guess the horizontal scroll amount is > something that's saved and restored by save-window-excursion. So I > finally settled on this: Note that the docs as you noted say that they restore the buffer, not the window. This was part of the point I was tyring to make. Buffers and windows are not the same thing. For example, you might use save-excursion in a command that needs to jump to another point in the buffer, perform some calculation, maybe put the results in a temp buffer or variable and then return to where things were at before the command executed. Essentially, your saving state of the buffer (not the window!) going off and doing something else and then once done, returning to where you were. In many cases, the user won't even realise this has occured. If on the other hand, you wanted to do something like display another window with some data, maybe a status message and then after the user hits a particular key, restore the window as it was, then save-window-excursion is probably what you want. In your current situation, you want to switch to the window displaying the buffer with the image in it, scroll it up/down or left/right and then return to where you were in the text buffer? I think you could either just use an unwind-protect or a save-excursion, but I'm a little confused regarding what the issue is with restoration. Strongly suggest you have a look at the sources to simple.el as it contains some examples of convenience commands related to scrolling. I also did an apropos-command with the search term 'scroll' and found the following which you might find useful - image-backward-hscroll M-x ... RET Scroll image in current window to the right by N character widths. image-forward-hscroll M-x ... RET Scroll image in current window to the left by N character widths. image-scroll-down M-x ... RET Scroll image in current window downward by N lines. image-scroll-up M-x ... RET Scroll image in current window upward by N lines. It would be fairly trivial to write two commands that would scroll the image up/down or left/right. It could take a prefix argument to determine the distance with positive arguments meaning donw/right and negative meaning up/left etc. I don't see there is any need to make it a macro unless you want to be able to execute arbitrarily complex forms. Maybe just write functions and later do a macro if justified. Tim -- tcross (at) rapttech dot com dot au ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: (save-excursion (other-window 1)) leaves me in the other window 2010-03-08 7:26 ` Tim X @ 2010-03-08 16:55 ` Sean McAfee 2010-03-08 17:02 ` Sean McAfee 2010-03-09 6:45 ` Tim X 0 siblings, 2 replies; 9+ messages in thread From: Sean McAfee @ 2010-03-08 16:55 UTC (permalink / raw) To: help-gnu-emacs Tim X <timx@nospam.dev.null> writes: > Sean McAfee <eefacm@gmail.com> writes: >> Although the documentation for save-excursion says that it saves and >> restores the current buffer, it doesn't in this case. > Note that the docs as you noted say that they restore the buffer, not > the window. This was part of the point I was tyring to make. Buffers and > windows are not the same thing. If the current buffer is restored, then I would expect this expression: (eq (current-buffer) (save-excursion arbitrary-forms (current-buffer))) ...to always evaluate to t regardless of what arbitrary-forms is, but it returns nil if I replace arbitrary-forms with (other-window 1). ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: (save-excursion (other-window 1)) leaves me in the other window 2010-03-08 16:55 ` Sean McAfee @ 2010-03-08 17:02 ` Sean McAfee 2010-03-08 17:24 ` David Kastrup 2010-03-09 6:45 ` Tim X 1 sibling, 1 reply; 9+ messages in thread From: Sean McAfee @ 2010-03-08 17:02 UTC (permalink / raw) To: help-gnu-emacs Sean McAfee <eefacm@gmail.com> writes: > If the current buffer is restored, then I would expect this expression: > > (eq (current-buffer) (save-excursion arbitrary-forms (current-buffer))) > > ...to always evaluate to t regardless of what arbitrary-forms is, but it > returns nil if I replace arbitrary-forms with (other-window 1). Argh. Of course the expression I meant to write was: (eq (current-buffer) (progn (save-excursion arbitrary-forms) (current-buffer))) This actually does return t in the presence of multiple windows even if arbitrary-forms is (other-window 1), and yet the cursor still ends up in a different window than the one it was in before evaluating the expression. I still don't get it. I guess maybe other-window doesn't switch windows immediately, but defers the switch until after the expression has been fully evaluated? ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: (save-excursion (other-window 1)) leaves me in the other window 2010-03-08 17:02 ` Sean McAfee @ 2010-03-08 17:24 ` David Kastrup 0 siblings, 0 replies; 9+ messages in thread From: David Kastrup @ 2010-03-08 17:24 UTC (permalink / raw) To: help-gnu-emacs Sean McAfee <smcafee@palantirtech.com> writes: > Sean McAfee <eefacm@gmail.com> writes: >> If the current buffer is restored, then I would expect this expression: >> >> (eq (current-buffer) (save-excursion arbitrary-forms (current-buffer))) >> >> ...to always evaluate to t regardless of what arbitrary-forms is, but it >> returns nil if I replace arbitrary-forms with (other-window 1). > > Argh. Of course the expression I meant to write was: > > (eq (current-buffer) (progn (save-excursion arbitrary-forms) (current-buffer))) > > This actually does return t in the presence of multiple windows even if > arbitrary-forms is (other-window 1), and yet the cursor still ends up in > a different window than the one it was in before evaluating the > expression. I still don't get it. I guess maybe other-window doesn't > switch windows immediately, but defers the switch until after the > expression has been fully evaluated? other-window changes the current window, not the current buffer. When Emacs returns to the command loop, the current buffer is set to the window-buffer of the current window. -- David Kastrup ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: (save-excursion (other-window 1)) leaves me in the other window 2010-03-08 16:55 ` Sean McAfee 2010-03-08 17:02 ` Sean McAfee @ 2010-03-09 6:45 ` Tim X 1 sibling, 0 replies; 9+ messages in thread From: Tim X @ 2010-03-09 6:45 UTC (permalink / raw) To: help-gnu-emacs Sean McAfee <eefacm@gmail.com> writes: > Tim X <timx@nospam.dev.null> writes: >> Sean McAfee <eefacm@gmail.com> writes: >>> Although the documentation for save-excursion says that it saves and >>> restores the current buffer, it doesn't in this case. > >> Note that the docs as you noted say that they restore the buffer, not >> the window. This was part of the point I was tyring to make. Buffers and >> windows are not the same thing. > > If the current buffer is restored, then I would expect this expression: > > (eq (current-buffer) (save-excursion arbitrary-forms (current-buffer))) > > ...to always evaluate to t regardless of what arbitrary-forms is, but it > returns nil if I replace arbitrary-forms with (other-window 1). I suspect your assuption is incorrect. The documentation for save-excursion does not explicitly state what its return value is. However, it does say that @body is executed 'just like progn'. The documentation for progn states that its return value is the return value of the last command executed. Documentation for other-window states that it returns nil, which would support the assumption that save-excursion returns values similar to progn, which in the case of other-window would be nil. There is certainly nothing I can see that would indicate save-excursion returns the same value as current-buffer i.e. a buffer object. Tim -- tcross (at) rapttech dot com dot au ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2010-03-09 6:45 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-03-05 20:33 (save-excursion (other-window 1)) leaves me in the other window Sean McAfee 2010-03-05 22:21 ` Joe Fineman 2010-03-07 6:55 ` Tim X 2010-03-08 3:09 ` Sean McAfee 2010-03-08 7:26 ` Tim X 2010-03-08 16:55 ` Sean McAfee 2010-03-08 17:02 ` Sean McAfee 2010-03-08 17:24 ` David Kastrup 2010-03-09 6:45 ` Tim X
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).