Added possibility to delete windows with prefix arg.

Cleaned up code and migrated to `defcustom'.
This commit is contained in:
Nikolaj Schumacher 2008-04-11 22:06:14 +02:00
parent bd4acd1f43
commit cec25d57b6

View file

@ -1,24 +1,30 @@
;;; window-numbering --- Emacs window shortcuts ;;; window-numbering --- Numbered window shortcuts
;;
;; Copyright (C) 2006-2007 Nikolaj Schumacher <bugs * nschum , de> ;; Copyright (C) 2006-2007 Nikolaj Schumacher <bugs * nschum , de>
;;
;;; License ;; Author: Nikolaj Schumacher <bugs * nschum de>
;; Version: 1.1.1
;; Keywords: faces, matching
;; URL: http://nschum.de/src/emacs/window-numbering-mode/
;; Compatibility: GNU Emacs 22.x
;;
;; This file is NOT part of GNU Emacs.
;;
;; This program is free software; you can redistribute it and/or ;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License ;; modify it under the terms of the GNU General Public License
;; as published by the Free Software Foundation; either version 2 ;; as published by the Free Software Foundation; either version 2
;; of the License, or (at your option) any later version. ;; of the License, or (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful, ;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details. ;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License ;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>. ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;
;;; Usage ;;; Commentary:
;;
;; Enable window-numbering-mode and use M-1 through M-0 to navigate. ;; Enable window-numbering-mode and use M-1 through M-0 to navigate.
;; ;;
;; If you want to affect the numbers, use window-numbering-before-hook or ;; If you want to affect the numbers, use window-numbering-before-hook or
@ -28,52 +34,70 @@
;; ;;
;; (setq window-numbering-assign-func ;; (setq window-numbering-assign-func
;; (lambda () (when (equal (buffer-name) "*Calculator*") 9))) ;; (lambda () (when (equal (buffer-name) "*Calculator*") 9)))
;;
;;; Changes Log:
;;; Changes ;;
;; 2008-04-11 (1.1.1)
;; Added possibility to delete window with prefix arg.
;; Cleaned up code and migrated to `defcustom'.
;;
;; 2007-02-18 (1.1) ;; 2007-02-18 (1.1)
;; added window-numbering-before-hook, window-numbering-assign-func ;; Added window-numbering-before-hook, window-numbering-assign-func.
;;
;;; Code:
;;; Configuration (eval-when-compile (require 'cl))
(defvar window-numbering-keymap (push "^No window numbered .$" debug-ignored-errors)
(let ((map (make-sparse-keymap)))
(define-key map "\M-0" 'select-window-0)
(define-key map "\M-1" 'select-window-1)
(define-key map "\M-2" 'select-window-2)
(define-key map "\M-3" 'select-window-3)
(define-key map "\M-4" 'select-window-4)
(define-key map "\M-5" 'select-window-5)
(define-key map "\M-6" 'select-window-6)
(define-key map "\M-7" 'select-window-7)
(define-key map "\M-8" 'select-window-8)
(define-key map "\M-9" 'select-window-9)
map)
"Keymap used in by `window-numbering-mode'.")
(defvar window-numbering-auto-assign-0-to-minibuffer t (defgroup window-numbering nil
"If non-nil, `window-numbering-mode' assigns 0 to the minibuffer if active.") "Numbered window shortcuts"
:group 'convenience)
(defcustom window-numbering-auto-assign-0-to-minibuffer t
"*If non-nil, `window-numbering-mode' assigns 0 to the minibuffer if active."
:group 'window-numbering
:type '(choice (const :tag "Off" nil)
(const :tag "On" t)))
(defcustom window-numbering-before-hook nil
"*Hook called before `window-numbering-mode' starts assigning numbers.
The number of windows that will be numbered is passed as a parameter.
Use `window-numbering-assign' to manually assign some of them a number.
If you want to assign a number to just one buffer, use
`window-numbering-assign-func' instead."
:group 'window-numbering
:type 'hook)
(defcustom window-numbering-assign-func nil
"*Function called for each window by `window-numbering-mode'.
This is called before automatic assignment begins. The function should
return a number to have it assigned to the current-window, nil otherwise."
:group 'window-numbering
:type 'function)
(defconst window-numbering-mode-line-position 1 (defconst window-numbering-mode-line-position 1
"The position in the mode-line `window-numbering-mode' displays the number.") "The position in the mode-line `window-numbering-mode' displays the number.")
(defvar window-numbering-before-hook nil (defun select-window-by-number (i &optional arg)
"Hook called before `window-numbering-mode' starts assigning numbers. "Select window given number I by `window-numbering-mode'.
The number of windows that will be numbered is passed as a parameter. If prefix ARG is given, delete the window instead of selecting it."
Use `window-numbering-assign' to manually assign some of them a number. (interactive "P")
If you want to assign a number to just one buffer, use (let ((windows (car (gethash (selected-frame) window-numbering-table)))
`window-numbering-assign-func' instead.") window)
(if (and (>= i 0) (< i 10)
(setq window (aref windows i)))
(if arg
(delete-window window)
(select-window window))
(error "No window numbered %s" i))))
(defvar window-numbering-assign-func nil ;; define interactive functions for keymap
"Function called for each window by `window-numbering-mode'. (dotimes (i 10)
This is called before automatic assignment begins. (eval `(defun ,(intern (format "select-window-%s" i)) (&optional arg)
The function should return a number to have it assigned to the current-window, ,(format "Select the window with number %i." i)
nil otherwise.") (interactive "P")
(select-window-by-number ,i arg))))
;;; Code
(require 'cl)
(defvar window-numbering-table nil (defvar window-numbering-table nil
"table -> (window vector . number table)") "table -> (window vector . number table)")
@ -87,11 +111,14 @@ nil otherwise.")
(decf i)) (decf i))
left)) left))
(defvar window-numbering-windows nil
"A vector listing the window for each number.")
(defvar window-numbering-numbers
"A hash map containing each window's number.")
(defvar window-numbering-left
"A list of unused window numbers.")
(defun window-numbering-assign (window &optional number) (defun window-numbering-assign (window &optional number)
(assert (boundp 'window-numbering-windows))
(assert (boundp 'window-numbering-numbers))
(assert (boundp 'window-numbering-left))
(if number (if number
(if (aref window-numbering-windows number) (if (aref window-numbering-windows number)
(progn (message "Number %s assigned to two buffers (%s and %s)" (progn (message "Number %s assigned to two buffers (%s and %s)"
@ -108,74 +135,32 @@ nil otherwise.")
(window-numbering-assign window number) (window-numbering-assign window number)
number))))) number)))))
(defun select-window-by-number (i)
"Select window given number I by `window-numbering-mode'."
(interactive)
(let ((windows (car (gethash (selected-frame) window-numbering-table)))
window)
(if (and (>= i 0) (< i 10)
(setq window (aref windows i)))
(select-window window)
(error "No window numbered %s" i))))
(defun window-numbering-update () (defun window-numbering-update ()
"Update the window numbering for the current frame. "Update the window numbering for the current frame.
Optional parameter PREASSIGNED-WINDOWS is a hashmap already mapping some Optional parameter PREASSIGNED-WINDOWS is a hashmap already mapping some
windows to numbers." windows to numbers."
(let* ((window-numbering-windows (make-vector 10 nil)) (setq window-numbering-windows (make-vector 10 nil)
(window-numbering-numbers (make-hash-table :size 10)) window-numbering-numbers (make-hash-table :size 10)
(window-numbering-left window-numbering-left
(window-numbering-calculate-left window-numbering-windows))) (window-numbering-calculate-left window-numbering-windows))
(puthash (selected-frame) (puthash (selected-frame)
(cons window-numbering-windows window-numbering-numbers) (cons window-numbering-windows window-numbering-numbers)
window-numbering-table) window-numbering-table)
(when (and window-numbering-auto-assign-0-to-minibuffer (when (and window-numbering-auto-assign-0-to-minibuffer
(active-minibuffer-window)) (active-minibuffer-window))
(window-numbering-assign (active-minibuffer-window) 0)) (window-numbering-assign (active-minibuffer-window) 0))
(let ((windows (window-list nil 0 (window-at 0 0)))) (let ((windows (window-list nil 0 (window-at 0 0))))
(run-hook-with-args 'window-numbering-before-hook windows) (run-hook-with-args 'window-numbering-before-hook windows)
(when window-numbering-assign-func (when window-numbering-assign-func
(mapc `(lambda (window) (mapc `(lambda (window)
(with-selected-window window (with-selected-window window
(with-current-buffer (window-buffer window) (with-current-buffer (window-buffer window)
(let ((num (funcall ,window-numbering-assign-func))) (let ((num (funcall ,window-numbering-assign-func)))
(when num (when num
(window-numbering-assign window num)))))) (window-numbering-assign window num))))))
windows)) windows))
(dolist (window windows) (dolist (window windows)
(window-numbering-assign window)) (window-numbering-assign window))))
)))
(defun select-window-0 ()
(interactive)
(select-window-by-number 0))
(defun select-window-1 ()
(interactive)
(select-window-by-number 1))
(defun select-window-2 ()
(interactive)
(select-window-by-number 2))
(defun select-window-3 ()
(interactive)
(select-window-by-number 3))
(defun select-window-4 ()
(interactive)
(select-window-by-number 4))
(defun select-window-5 ()
(interactive)
(select-window-by-number 5))
(defun select-window-6 ()
(interactive)
(select-window-by-number 6))
(defun select-window-7 ()
(interactive)
(select-window-by-number 7))
(defun select-window-8 ()
(interactive)
(select-window-by-number 8))
(defun select-window-9 ()
(interactive)
(select-window-by-number 9))
(defun window-numbering-get-number-string (&optional window) (defun window-numbering-get-number-string (&optional window)
(int-to-string (window-numbering-get-number window))) (int-to-string (window-numbering-get-number window)))
@ -184,6 +169,22 @@ windows to numbers."
(gethash (or window (selected-window)) (gethash (or window (selected-window))
(cdr (gethash (selected-frame) window-numbering-table)))) (cdr (gethash (selected-frame) window-numbering-table))))
(defvar window-numbering-keymap
(let ((map (make-sparse-keymap)))
(define-key map "\M-0" 'select-window-0)
(define-key map "\M-1" 'select-window-1)
(define-key map "\M-2" 'select-window-2)
(define-key map "\M-3" 'select-window-3)
(define-key map "\M-4" 'select-window-4)
(define-key map "\M-5" 'select-window-5)
(define-key map "\M-6" 'select-window-6)
(define-key map "\M-7" 'select-window-7)
(define-key map "\M-8" 'select-window-8)
(define-key map "\M-9" 'select-window-9)
map)
"Keymap used in by `window-numbering-mode'.")
;;;###autoload
(define-minor-mode window-numbering-mode (define-minor-mode window-numbering-mode
"A minor mode that assigns a number to each window." "A minor mode that assigns a number to each window."
nil nil window-numbering-keymap :global t nil nil window-numbering-keymap :global t
@ -230,3 +231,5 @@ windows to numbers."
(force-mode-line-update t)) (force-mode-line-update t))
(provide 'window-numbering) (provide 'window-numbering)
;;; window-numbering.el ends here