;;; -*- Mode:Emacs-Lisp -*- ;;; Various window manipulation commands optimized for slow terminal lines... ;;; By Jamie Zawinski (defvar split-window-track-cursor t "*If this is true, then the `split-window-vertically-carefully' command will leave the cursor either in the top window or the bottom window, depending on where the cursor was before the split. If this is false, then the cursor is always left in the top window.") (defun split-window-vertically-carefully (&optional arg) "Split current window into two windows, one above the other. The uppermost window will get at most ARG lines (no arg means split equally). Both windows will be displaying the current buffer, but the second window will be scrolled such that little redisplay will happen - the lines that were on the screen before the split will still be on the screen, in the same places. If the variable 'split-window-track-cursor' is true, then an effort is made to keep the cursor in the same place relative to the text on the screen as well. If the cursor is below the half-way point in the window before the split, then it will be moved to the bottom window; otherwise it will be in the top window. If 'split-window-track-cursor' is false, then the cursor will always be left in the top window, even if that means that the point must be moved." (interactive "P") (let ((p (point))) (goto-char (window-start)) (let ((topp (point))) (split-window nil (and arg (prefix-numeric-value arg))) (let* ((top (selected-window)) (toph (window-height top)) (stay-in-top t)) (goto-char topp) ; undo any scrolling that split-window may have done. (recenter 0) (if (< (count-lines (point) p) toph) ; if cursor fits in top window (goto-char p) ; then keep it there; otherwise (setq stay-in-top nil) ; move the point to EOW, and the (forward-line (- toph 2))) ; cursor to the bottom window. (select-window (next-window)) (goto-char topp) ; undo any scrolling that split-window may have (recenter 0) ; done. (condition-case () (scroll-up toph) ;; ignore errors in case we are already at EOB. (error nil)) (goto-char (window-start)) (if (< (count-lines (point) p) (window-height)) ; if cursor fits in bottom window, keep it there. (goto-char p)) ;; move cursor back to top window if appropriate. (if (or stay-in-top (null split-window-track-cursor)) (select-window top)))))) (defun delete-other-windows-carefully () "Like delete-other-windows, but conspires to make the cursor remain in the same position on the screen - the lines that stay the same will not be scrolled up." (interactive) (let ((p (point))) (goto-char (window-start)) (let ((top (car (cdr (window-edges))))) (delete-other-windows) (recenter 0) (condition-case c (scroll-down top) (beginning-of-buffer nil) (end-of-buffer nil))) (goto-char p))) (or (fboundp 'window-edges) (fset 'delete-other-windows-carefully 'delete-other-windows)) (provide 'window-hacks)