I have configured Emacs to save my desktop when I close it, so that when I open it next all my buffers are reopened.
However my init.el splits the frame into three windows at startup, so I can view three buffers on the screen at the same time. The first window already shows the buffer I was last editing, but I would like the other two windows to show the second and third last files I was editing too.
I thought this would be possible using something like this:
;; Split into three equally sized windows
(split-window-horizontally)
(split-window-horizontally)
(balance-windows)
;; Load some buffers into the new windows
(other-window 1)
(next-buffer) ; Shows *Messages* in both windows
;(previous-buffer) ; same
;(switch-to-buffer 'nil t) ; Shows same buffer in both windows
(other-window 1)
(next-buffer)
(previous-multiframe-window)
(previous-multiframe-window)
Unfortunately I can't find a command to select the buffer I want in each window. If I manually type C-x b RET in each window then it selects exactly the buffers I want (and they are different in each window), but I can't figure out how to replicate that behaviour as a command in init.el.
What am I doing wrong?
If the window is selected then you can use
(set-window-buffer (selected-window) "name of buffer")
Related
I have many buffers open in an Emacs window. I want to move one of the buffers to a new window. Is there a command which does that?
The command you are looking for is tear-off-window. Note that this command must be associated with a mouse click event.
For example, you can put the following code (from this reddit comment) in your init file (more about init file here):
(global-set-key [mode-line C-mouse-1] 'tear-off-window)
This will call tear-off-window when you Control-click on the buffer modeline.
If you want to use a keyboard binding, the modified version of tear-off-window is below. Put it into your init file to save it after restarting emacs.
(bind-key "C-x C-X" #'my/tear-off-window)
(defun my/tear-off-window ()
"Delete the selected window, and create a new frame displaying its buffer."
(interactive)
(let* ((window (selected-window))
(buf (window-buffer window))
(frame (make-frame)))
(select-frame frame)
(switch-to-buffer buf)
(delete-window window)))
In the code, the modified command is bind to "C-x C-X". You are free to change it to any other key sequence (more details here).
IIUC, you want to create a new WM window.
Emacs uses a slightly different terminology: what are usually called "windows" in a GUI environment, Emacs calls "frames". WIthin a single frame, Emacs subdivides its area into separate "windows" (IOW, even in a non-GUI environment, Emacs acts as a "tiling" window manager). So, you can create a new frame with C-x 5 2 (or equivalently M-x make-frame-command RET) and then in that frame, switch to the required buffer with C-x b <buffer-name> RET.
Note by the way, that you don't "move" the buffer to the new frame: the buffer exists independently of whether there is a (emacs) window in a frame that displays the buffer.
I was wondering if there is a way in Emacs lisp to jump back to the last active window, just as popd would do in Linux?
The reason I ask is that in some environments for evaluating code (e.g. babel-repl) the editing area for the source code loses focus to the REPL once the REPL is launched. I'd like to change its behavior and switch the focus back to the editing area, e.g., by adding an additional command in elisp to jump back to the last active window before launching the REPL.
previous-window or get-mru-window should do what you want. You can then switch with
(select-window (previous-window))
If you are interested in switching just the active buffer, you can use:
(defun prev-window ()
(interactive)
(other-window -1))
(global-set-key [(f12)] 'prev-window)
(global-set-key "\C-cp" 'prev-window)
(global-set-key "\C-cn" 'other-window)
I have this in my ~/.emacs file. CTRL+C then p (or F12) to go to the previous buffer. CTRL+C then n to go to the next buffer. The function other-buffer lets you revisit the last visited buffer. By supplying a negative number you can reverse the order that it goes through the buffer list.
I know it is a bad habit to use a mouse as an Emacs user. However, there are times when it is just convenient to close "some" of my multiple Emacs frames by clicking the red "x" Close button on the upper left corner of Finder rather than just repeatedly using C-x 4 0.
Is there is a way to rebind OS X GUI Close button to kill (C-x 4 0) the buffer of a frame - that is, kill the buffer and the frame at the same time? And if the buffer has no filename, Emacs will ask me to save or discard the buffer.
My Emacs is 24.3.1 on OS X.
First, it is not a bad idea to use a mouse with Emacs. Quite the contrary. But it can be a bad habit, as you say: anything overdone can be a bad habit. Emacs works especially well with a mouse (the Emacs mouse is more powerful than usual), and it works fine without a mouse. Use a mouse for what it is good for: direct access to any position, just by pointing.
And yes, you can make Emacs perform a command (such as delete-frame) when you click the window-manager X icon (or whatever icon your window manager uses to delete windows). You do this:
(define-key special-event-map [delete-frame] 'delete-frame)
See (elisp) Special Events.
(In library thumb-frm.el I use the Minimize icon (optionally) to thumbify frames, as another example of this.)
To answer your comment question more specifically. This code prompts for the buffer to kill (default: current buffer). If there is only one frame, then it quits Emacs. Otherwise, it deletes only the selected frame.
(defun foo (&optional buffer)
(interactive (list (read-buffer "Buffer: " (current-buffer))))
(if (not (cadr (frame-list)))
(save-buffers-kill-terminal) ; Kill Emacs, if last frame
(kill-buffer buffer)
(delete-frame (selected-frame) 'FORCE)))
(define-key special-event-map [delete-frame] 'foo)
In an Emacs dired buffer, if I navigate point over a filename and hit o for dired-find-file-other-window, dired successfully produces desired behavior: opening the file in a secondary window.
But if I then navigate point over a SECOND filename and again hit o, dired splits the frame AGAIN and opens the file in a THIRD window.
How do I direct dired to reuse the second window, such that I always have a maximum of two windows in a frame?
Tried to solve the same problem using by modifying value of split-width-threshold, but found that it often stops working when monitor configuration changes. Ended up writing an advice for window-splittable-p.
(setq split-width-threshold (- (window-width) 10))
(setq split-height-threshold nil)
(defun count-visible-buffers (&optional frame)
"Count how many buffers are currently being shown. Defaults to selected frame."
(length (mapcar #'window-buffer (window-list frame))))
(defun do-not-split-more-than-two-windows (window &optional horizontal)
(if (and horizontal (> (count-visible-buffers) 1))
nil
t))
(advice-add 'window-splittable-p :before-while #'do-not-split-more-than-two-windows)
Raise value of split-height-threshold to the extend it will not do another split.
You might have to raise split-width-threshold also - in case Emacs thinks it's smart to split that way than.
WRT questions in comment:
The value to choose IMO depends from number of lines displayed at window. Let's assume 40 lines are displayed. If a window is split, 20 are left. Then a `split-height-threshold' of 15 should prevent further split. Preventing further side-by-side split should work respective, just consider the columns displayed.
BTW would expect a way to adapt that dynamically.
When switching buffers with emacs ido mode enabled, a list of completions are displayed in the minibuffer. It appears there is a "feature" that buffers that are already open are put to the end of the list. I, however, often open the same buffer in multiple panes.
Is there a way to either turn this "feature" off, or alternatively do the opposite: have the buffers that are already open be at the front of the completion list?
The main point of ido mode is that you don't use arrows to navigate between buffers in the minibuffer. Instead you type the part of the buffer's name. In this case it doesn't matter where the buffer is in the list.
This is not possible unless you want to wade deep in ido's intestines.
As eGlyph already said: You're likely using ido wrongly (and there's also C-s for <right> and C-r for <left>; no need for arrow keys).
But you can define command for choosing among the already shown buffers (here only from the current frame, if you want all shown buffers you have to collect the windows first via `frame-list):
(defun choose-from-shown-buffers ()
(interactive)
(let ((buffers (mapcar (lambda (window)
(buffer-name (window-buffer window)))
(window-list))))
(pop-to-buffer (ido-completing-read "Buffer: " buffers))))