mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-06 06:20:55 -08:00
New commands to split and merge frames
* lisp/window-x.el (merge-frames, split-frame): New commands.
This commit is contained in:
parent
8fc068a15d
commit
db6ac3c5f4
2 changed files with 109 additions and 2 deletions
109
lisp/window-x.el
109
lisp/window-x.el
|
|
@ -313,7 +313,114 @@ ones in `window--transpose'."
|
||||||
(let ((is-atom (memq (cadr (cadr (cddddr subtree))) atom-windows)))
|
(let ((is-atom (memq (cadr (cadr (cddddr subtree))) atom-windows)))
|
||||||
(window--transpose-1 (car (cddddr subtree)) cwin
|
(window--transpose-1 (car (cddddr subtree)) cwin
|
||||||
(if is-atom '(nil . t) conf)
|
(if is-atom '(nil . t) conf)
|
||||||
no-resize atom-windows)))))
|
no-resize atom-windows)))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun merge-frames (&optional vertical frame1 frame2)
|
||||||
|
"Merge FRAME2 into FRAME1.
|
||||||
|
Split the root window of FRAME1 and make the new window display the root
|
||||||
|
window of FRAME2. Both FRAME1 and FRAME2 must be live frames. If
|
||||||
|
VERTICAL is non-nil, make the new window below the old root window of
|
||||||
|
FRAME1. Otherwise, make the new window on the right of FRAME1's root
|
||||||
|
window. Interactively, VERTICAL is the prefix argument, FRAME1 is the
|
||||||
|
selected frame and FRAME2 is the frame following FRAME1 in the frame
|
||||||
|
list."
|
||||||
|
(interactive "P")
|
||||||
|
(let* ((frame1 (window-normalize-frame frame1))
|
||||||
|
(frame2 (if frame2
|
||||||
|
(window-normalize-frame frame2)
|
||||||
|
(next-frame frame1))))
|
||||||
|
(window-state-put
|
||||||
|
;; Source window on frame2.
|
||||||
|
(window-state-get (window-main-window frame2))
|
||||||
|
;; Make new window on frame1.
|
||||||
|
(split-window (window-main-window frame1) nil (null vertical)))
|
||||||
|
(delete-frame frame2)
|
||||||
|
frame1))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun split-frame (&optional arg frame)
|
||||||
|
"Split FRAME.
|
||||||
|
FRAME must be a live frame and defaults to the selected one.
|
||||||
|
|
||||||
|
Interactively, ARG is the prefix argument. If ARG is a number, make ARG
|
||||||
|
- 1 new frames and put any child window of the main window of FRAME into
|
||||||
|
one of these frames. As a special case, if ARG equals 1, make one new
|
||||||
|
frame containing all children but the first of the root window of FRAME.
|
||||||
|
With a non-numeric prefix ARG, try to put all children of FRAME's main
|
||||||
|
window but the first into a new frame. In either case, any window put
|
||||||
|
on a new frame is a clone of the original window and the original window
|
||||||
|
is deleted."
|
||||||
|
(interactive "P")
|
||||||
|
(let* ((mw (window-main-window frame))
|
||||||
|
(first-child (window-child mw))
|
||||||
|
(nwindows (window-child-count mw)))
|
||||||
|
(cond
|
||||||
|
((or (<= nwindows 1))
|
||||||
|
(error "Cannot split a one-window frame"))
|
||||||
|
;; One frame for each window.
|
||||||
|
((or (eq nwindows 2) (and arg (not (numberp arg))))
|
||||||
|
(let ((sib (window-next-sibling first-child))
|
||||||
|
frames)
|
||||||
|
(while sib
|
||||||
|
(let* ((state (window-state-get sib))
|
||||||
|
(frame (make-frame))
|
||||||
|
(next-sib (window-next-sibling sib)))
|
||||||
|
(push frame frames)
|
||||||
|
(window-state-put state (window-main-window frame))
|
||||||
|
(delete-window sib)
|
||||||
|
(setq sib next-sib)))
|
||||||
|
frames))
|
||||||
|
;; Two windows.
|
||||||
|
((eq 1 arg)
|
||||||
|
(let* ((snd-sib (window-next-sibling first-child))
|
||||||
|
(sib (combine-windows snd-sib (window-last-child mw)))
|
||||||
|
(state (window-state-get sib))
|
||||||
|
(frame (make-frame)))
|
||||||
|
(window-state-put state (window-main-window frame))
|
||||||
|
(delete-window sib)
|
||||||
|
frame))
|
||||||
|
;; Smart window splitting.
|
||||||
|
(t
|
||||||
|
(let ((nframes (or arg 2)))
|
||||||
|
(when (< nwindows nframes)
|
||||||
|
(error "%i frames cannot be made from %i windows" arg nwindows))
|
||||||
|
(let* ((horizontal (window-combined-p first-child t))
|
||||||
|
(ideal (/ (window-size mw horizontal) nframes))
|
||||||
|
(current-window first-child)
|
||||||
|
(sum (window-size current-window horizontal))
|
||||||
|
(windows (list (list first-child)))
|
||||||
|
frames)
|
||||||
|
;; Need to come up with the inital windows split using sliding
|
||||||
|
;; sum technique.
|
||||||
|
(while (setq current-window (window-next-sibling current-window))
|
||||||
|
(setq sum (seq-reduce '+ (mapcar
|
||||||
|
(lambda (w)
|
||||||
|
(window-size w horizontal))
|
||||||
|
(car (last windows)))
|
||||||
|
0))
|
||||||
|
(let ((remaining-frames (- nframes (length windows)))
|
||||||
|
(remaining-windows
|
||||||
|
(- nwindows (seq-reduce '+ (mapcar 'length windows) 0))))
|
||||||
|
(if (or (= remaining-windows remaining-frames)
|
||||||
|
;; HACK ALERT!
|
||||||
|
(>= sum (* ideal 0.85)))
|
||||||
|
(progn
|
||||||
|
(setq sum 0)
|
||||||
|
(nconc windows (list (list current-window))))
|
||||||
|
(nconc (car (last windows)) (list current-window)))))
|
||||||
|
(when (cdar windows)
|
||||||
|
(combine-windows (caar windows) (car (last (car windows)))))
|
||||||
|
(dolist (wls (cdr windows) frames)
|
||||||
|
(let* ((cwin (if (cdr wls)
|
||||||
|
(combine-windows (car wls) (car (last wls)))
|
||||||
|
(car wls)))
|
||||||
|
(state (window-state-get cwin))
|
||||||
|
(frame (make-frame)))
|
||||||
|
(push frame frames)
|
||||||
|
(delete-window cwin)
|
||||||
|
(window-state-put state (window-main-window frame))))))))))
|
||||||
|
|
||||||
(provide 'window-x)
|
(provide 'window-x)
|
||||||
|
|
||||||
;;; window-x.el ends here
|
;;; window-x.el ends here
|
||||||
|
|
|
||||||
|
|
@ -2072,7 +2072,7 @@ dump_interval_tree (struct dump_context *ctx,
|
||||||
static dump_off
|
static dump_off
|
||||||
dump_string (struct dump_context *ctx, const struct Lisp_String *string)
|
dump_string (struct dump_context *ctx, const struct Lisp_String *string)
|
||||||
{
|
{
|
||||||
#if CHECK_STRUCTS && !defined (HASH_Lisp_String_03B2DF1C8E)
|
#if CHECK_STRUCTS && !defined (HASH_Lisp_String_B71C8876EB)
|
||||||
# error "Lisp_String changed. See CHECK_STRUCTS comment in config.h."
|
# error "Lisp_String changed. See CHECK_STRUCTS comment in config.h."
|
||||||
#endif
|
#endif
|
||||||
/* If we have text properties, write them _after_ the string so that
|
/* If we have text properties, write them _after_ the string so that
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue