if I eval
(with-current-buffer "xx"
(goto-char(point-max)))
when the buffer xx is buried, point is NOT moved after I
switch to it.
it's driving me crazy after sifting my code for a
bug for 5 days only to find it isn't one but a maddening
behaviour I can find no documentation for nor search results relating to.
You moved point to where you wanted in that buffer, but not in any window. The buffer in question need never be displayed. with-current-buffer lets Lisp code do stuff in a buffer. You're confusing window-point with point.
Try this, to see the difference, assuming that your buffer xx is displayed in some visible window on some frame (or use t instead of visible if it's in an invisible window):
(with-current-buffer "xx"
(goto-char 5000)
(message "PT: %S, WINDOW PT: %S"
(point)
(window-point (get-buffer-window "xx" 'visible))))
You can use function set-window-point to set the window-point. See the Elisp manual, node Window Point.
from a reading of the source it appears emacs keeps a list of previously seen buffers per window (window-prev-buffers) recording the cursor position that prevailed at the time of last viewing.
switch-to-buffer, the standard way of raising a buffer, consults switch-to-buffer-preserve-window-point in deciding whether to restore this saved cursor position when a previously seen buffer is revisited by a window.
by setting the variable to nil the buffer's actual point is used as the window point.
this gets the behaviour I want although the variable is not consulted on a buffer local basis so setting has to be global (or local to the buffer one happens to be switching from!) which is undesirable since I can't say there are no alternate universes out there where it's useful for a window and buffer to not agree on where the cursor is.
Related
Often I have multiples windows carefully arranged within a frame.
However, certain command, say M-x man RET will grab one of the visible windows to display its own content. Sometimes this is annoying because the window that was taken away is one that I need to keep it visible.
e.g. I have 3 windows on screen, one useful source-code window and two useless windows. I want to keep the soure-code window visible while checking the man page. But very often Emacs just take away the code-window for the newly opened man page.
One way I can think of is to display the (chronological) open order of each window, so that I can focus point on n-th window and be confident that Emacs will grab (n+1)-th window for new content.
Is there a way to display such order, e.g. in the mode-line of each window?
Or is there another way for better control for displaying new window?
A little late to the party but as discussed in the comments, using dedicated windows is a good way to control where new content is displayed (+1 to #lawlist for bringing it up and to #phils for mentioning toggling!).
I'm pretty sure you'd be able to implement a command that toggles dedicatedness yourself at this point, but since I have the code for this handy I'll share it anyway:
(defun toggle-window-dedicated ()
"Control whether or not Emacs is allowed to display another
buffer in current window."
(interactive)
(message
(if (let (window (get-buffer-window (current-buffer)))
; set-window-dedicated-p returns FLAG that was passed as
; second argument, thus can be used as COND for if:
(set-window-dedicated-p window (not (window-dedicated-p window))))
"%s: Can't touch this!"
"%s is up for grabs.")
(current-buffer)))
(global-set-key (kbd "C-c d") 'toggle-window-dedicated)
Now, in a multi-window setup you can simply press C-c d in each window you would like to "protect".
I'll throw this example usage of display-buffer-alist into the mix, given that it was mentioned in the comments, and is indeed a general mechanism for controlling how and where buffers are displayed (even though, as Drew indicates, it is far from trivial).
Start with the help for the variable itself:
C-hv display-buffer-alist RET
From there you'll get to the help for display-buffer, and no doubt acquire some idea of the complexities involved :)
In any case, the following is an example of using a custom function to decide how to display buffers named *Buffer List*.
You can easily see that if you can write a function which can figure out how to display a buffer where you want it to, then you can use display-buffer-alist to make it happen.
(defun my-display-buffer-pop-up-same-width-window (buffer alist)
"A `display-buffer' ACTION forcing a vertical window split.
See `split-window-sensibly' and `display-buffer-pop-up-window'."
(let ((split-width-threshold nil)
(split-height-threshold 0))
(display-buffer-pop-up-window buffer alist)))
(add-to-list 'display-buffer-alist
'("\\*Buffer List\\*" my-display-buffer-pop-up-same-width-window))
A key quote regarding the ACTION functions is:
Each such FUNCTION should accept two arguments: the buffer to
display and an alist. Based on those arguments, it should
display the buffer and return the window.
Every now and then Emacs develops this annoying behaviour of remembering a position in a buffer. Whenever I leave the buffer and return the point automatically moves back to the same position.
I probably hit some random command without being aware of it, but does anyone know what this is and how I can stop it?
I think saveplace is useful in such case.
you add following S-exp in your configuration file.
(load "saveplace")
(setq-default save-place t)
See Also
http://www.emacswiki.org/emacs/SavePlace
I'd like to recenter a buffer, called *Lense*, where I've inserted some text. I wished to make it the current buffer by (set-buffer "*Lense*"), then (recenter 0)). By the following code segments:
(save-excursion (set-buffer "*Lense*")
(recenter 0))
However, it seems that the above code would only recenter the buffer which is the current buffer, and (set-buffer "*Lense*") has no effect to make the current buffer to be *Lense*.
Please help me to figure out the right way to recenter the named buffer *Lense*.
If the buffer you want to recenter is visible, then you want to recenter its window.
(with-selected-window (get-buffer-window "*Lense*")
(recenter 0))
This will blow up if the buffer is not being displayed, so you may want to condition-case or unwind-protect.
If you want to handle the case where the buffer is not visible, you need to move the point. The window that will eventually display the buffer will center near the point, so you will have to move the point somewhere that will make that happen. Seems like your insert operation will DTRT, so you don't need to worry in that case.
I have not found (recenter) function, but there is (recenter-top-bottom). You can try using it instead of (recenter). Standard C-l hotkey calls exactly this function (recenter-top-bottom), also it has optional argument, line of window, which can be passed by C-u arg C-l.
PS: I can be wrong because I'm not familiar with emacs-lisp, I'm just using emacs with minimal customizations.
In Emacs (23 on Mac Leopard), I've discovered how to highlight the current line with hl-line-mode, but when using it globally in all buffers, it highlights the current line in all buffers in all frames.
I'd like to be able to highlight the current line (or at least have a different face for it) in only the currently active buffer. I'm sure this must be possible to some degree as the cursor changes dependent on whether the buffer is the current one or not.
Thanks
Singletoned
Looking at the documentation for hl-line-mode, it appears that you might have the variable hl-line-sticky-flag turned on. Try
C-h v hl-line-sticky-flag
to see if it's non-nil, and if so, then add
(setq hl-line-sticky-flag nil)
to your .emacs.
I'm looking for a way to send the output of an arbitrary Emacs command (in my case sql-send-region) to another window. I would prefer to maintain focus in the window I am currently in, which would effectively give me one window to edit queries and one window to view the output.
I was able to write some Emacs Lisp to solve my problem:
(defun sql-send-region-and-return (start end)
(interactive "r")
(let ((oldbuf (buffer-name)))
(sql-send-region start end)
(switch-to-buffer oldbuf)))
This sends the result of your region to the SQL buffer and returns back to your current buffer, effectively accomplishing the stated objective.
Thanks justinhj for giving me some new leads to solve my problem.
Have you tried setting this variable to t, it sounds like the behaviour you want.
sql-pop-to-buffer-after-send-region
After a call to sql-send-region' orsql-send-buffer',
the window is split and the SQLi buffer is shown. If this
variable is not nil, that buffer's window will be selected
by calling pop-to-buffer'. If this variable is nil, that
buffer is shown usingdisplay-buffer'.