Skip to content

Commit

Permalink
added window-numbering.el (thanks to bin chen)
Browse files Browse the repository at this point in the history
  • Loading branch information
syl20bnr committed Feb 3, 2013
1 parent effcace commit 0931e4a
Show file tree
Hide file tree
Showing 8 changed files with 299 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,6 @@
[submodule "extensions/elixir-mode"]
path = extensions/elixir-mode
url = http://github.com/antifuchs/elixir-mode
[submodule "extensions/window-numbering"]
path = extensions/window-numbering
url = http://github.com/nschum/window-numbering.el
1 change: 1 addition & 0 deletions extensions.el
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
elixir-mode
pylookup
;; pymacs
window-numbering
))

;; load extensions
Expand Down
2 changes: 2 additions & 0 deletions extensions/window-numbering/.dir-locals.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
((nil . ((indent-tabs-mode . nil)
(fill-column . 80))))
1 change: 1 addition & 0 deletions extensions/window-numbering/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.elc
35 changes: 35 additions & 0 deletions extensions/window-numbering/window-numbering-tests.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
(require 'elk-test)

(deftest "window-numbering-assign"
(let ((window-numbering-windows (make-vector 10 nil))
(window-numbering-numbers (make-hash-table :size 10))
(window-numbering-left '(1 2 3)))
(assert-nonnil (window-numbering-assign 'xx 7))
(assert-nil (window-numbering-assign 'yy 7))
(assert-nonnil (window-numbering-assign 'zz 8))
(assert-equal 8 (gethash 'zz window-numbering-numbers))
(assert-equal 7 (gethash 'xx window-numbering-numbers))
(assert-equal 'zz (aref window-numbering-windows 8))
(assert-equal 'xx (aref window-numbering-windows 7))
))

(deftest "window-numbering-assign auto"
(let ((window-numbering-windows (make-vector 10 nil))
(window-numbering-numbers (make-hash-table :size 10))
(window-numbering-left '(1 2 3 4)))
(assert-eq 1 (window-numbering-assign 'xx))
(assert-nonnil (window-numbering-assign 'yy 3))
(assert-eq 2 (window-numbering-assign 'zz))
(assert-eq 4 (window-numbering-assign 'aa))
))


(deftest "window-numbering-calculate-left"
(assert-equal '(6) (window-numbering-calculate-left
[t t t t t nil t t t t]))
(assert-equal '(1 2 3) (window-numbering-calculate-left
[nil nil nil t t t t t t t]))
(assert-equal '(1 2 3 4 5 6 7 8 9 0)
(window-numbering-calculate-left
[nil nil nil nil nil nil nil nil nil nil]))
)
243 changes: 243 additions & 0 deletions extensions/window-numbering/window-numbering.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
;;; window-numbering --- Numbered window shortcuts
;;
;; Copyright (C) 2006-2007, 2013 Nikolaj Schumacher <bugs * nschum , de>
;;
;; 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, GNU Emacs 23.x, GNU Emacs 24.x
;;
;; This file is NOT part of GNU Emacs.
;;
;; This program is free software; you can redistribute it and/or
;; modify it under the terms of the GNU General Public License
;; as published by the Free Software Foundation; either version 2
;; of the License, or (at your option) any later version.
;;
;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.
;;
;;; Commentary:
;;
;; 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
;; window-numbering-assign-func.
;; For instance, to always assign the calculator window the number 9, add the
;; following to your .emacs:
;;
;; (setq window-numbering-assign-func
;; (lambda () (when (equal (buffer-name) "*Calculator*") 9)))
;;
;;; Changes Log:
;;
;; Fix numbering in terminal mode with menu bar visible.
;; Add face for window number. (thanks to Chen Bin)
;;
;; 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)
;; Added window-numbering-before-hook, window-numbering-assign-func.
;;
;;; Code:

(eval-when-compile (require 'cl))

(push "^No window numbered .$" debug-ignored-errors)

(defgroup window-numbering nil
"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
"The position in the mode-line `window-numbering-mode' displays the number.")

(defface window-numbering-face '()
"Face used for the number in the mode-line."
:group 'window-numbering)

(defun select-window-by-number (i &optional arg)
"Select window given number I by `window-numbering-mode'.
If prefix ARG is given, delete the window instead of selecting it."
(interactive "P")
(let ((windows (car (gethash (selected-frame) window-numbering-table)))
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))))

;; define interactive functions for keymap
(dotimes (i 10)
(eval `(defun ,(intern (format "select-window-%s" i)) (&optional arg)
,(format "Select the window with number %i." i)
(interactive "P")
(select-window-by-number ,i arg))))

(defvar window-numbering-table nil
"table -> (window vector . number table)")

(defun window-numbering-calculate-left (windows)
(let ((i 9) left)
(while (>= i 0)
(let ((window (aref windows i)))
(unless window
(push (% (1+ i) 10) left)))
(decf i))
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)
(if number
(if (aref window-numbering-windows number)
(progn (message "Number %s assigned to two buffers (%s and %s)"
number window (aref window-numbering-windows number))
nil)
(setf (aref window-numbering-windows number) window)
(puthash window number window-numbering-numbers)
(setq window-numbering-left (delq number window-numbering-left))
t)
;; else default adding
(when window-numbering-left
(unless (gethash window window-numbering-numbers)
(let ((number (car window-numbering-left)))
(window-numbering-assign window number)
number)))))

(defun window-numbering-update ()
"Update the window numbering for the current frame.
Optional parameter PREASSIGNED-WINDOWS is a hashmap already mapping some
windows to numbers."
(setq window-numbering-windows (make-vector 10 nil)
window-numbering-numbers (make-hash-table :size 10)
window-numbering-left
(window-numbering-calculate-left window-numbering-windows))
(puthash (selected-frame)
(cons window-numbering-windows window-numbering-numbers)
window-numbering-table)
(when (and window-numbering-auto-assign-0-to-minibuffer
(active-minibuffer-window))
(window-numbering-assign (active-minibuffer-window) 0))
(let ((windows (window-list nil 0 (frame-first-window))))
(run-hook-with-args 'window-numbering-before-hook windows)
(when window-numbering-assign-func
(mapc `(lambda (window)
(with-selected-window window
(with-current-buffer (window-buffer window)
(let ((num (funcall ,window-numbering-assign-func)))
(when num
(window-numbering-assign window num))))))
windows))
(dolist (window windows)
(window-numbering-assign window))))

(defun window-numbering-get-number-string (&optional window)
(let ((s (concat " |" (int-to-string (window-numbering-get-number window)) "| ")))
(propertize s 'face 'window-numbering-face)))

(defun window-numbering-get-number (&optional window)
(gethash (or window (selected-window))
(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
"A minor mode that assigns a number to each window."
nil nil window-numbering-keymap :global t
(if window-numbering-mode
(unless window-numbering-table
(save-excursion
(setq window-numbering-table (make-hash-table :size 16))
(window-numbering-install-mode-line)
(add-hook 'window-configuration-change-hook
'window-numbering-update)
(dolist (frame (frame-list))
(select-frame frame)
(window-numbering-update))))
(window-numbering-clear-mode-line)
(remove-hook 'window-configuration-change-hook
'window-numbering-update)
(setq window-numbering-table nil)))

(defun window-numbering-install-mode-line (&optional position)
"Install the window number from `window-numbering-mode' to the mode-line."
(let ((mode-line (default-value 'mode-line-format))
(res))
(dotimes (i (min (or position window-numbering-mode-line-position)
(length mode-line)))
(push (car mode-line) res)
(pop mode-line))
(push '(:eval (window-numbering-get-number-string)) res)
(while mode-line
(push (car mode-line) res)
(pop mode-line))
(setq-default mode-line-format (nreverse res)))
(force-mode-line-update t))

(defun window-numbering-clear-mode-line ()
"Remove the window number of `window-numbering-mode' from the mode-line."
(let ((mode-line (default-value 'mode-line-format))
(res))
(while mode-line
(let ((item (car mode-line)))
(unless (equal item '(:eval (window-numbering-get-number-string)))
(push item res)))
(pop mode-line))
(setq-default mode-line-format (nreverse res)))
(force-mode-line-update t))

(provide 'window-numbering)

;;; window-numbering.el ends here
2 changes: 2 additions & 0 deletions init-extension/init-window-numbering.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
(require 'window-numbering)
(window-numbering-mode 1)
14 changes: 12 additions & 2 deletions my-keybindings.el
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@

;; First unset shortcuts which shadow evil leader =============================
;; Unset shortcuts which shadow evil leader =============================
(eval-after-load "compile"
(define-key compilation-mode-map (kbd "SPC") nil))

Expand Down Expand Up @@ -27,6 +26,17 @@
(evil-leader/set-key ":" 'smex)
;; ace-jump -------------------------------------------------------------------
(evil-leader/set-key "SPC" 'ace-jump-mode)
;; switch window by number ----------------------------------------------------
(evil-leader/set-key "0" 'select-window-0)
(evil-leader/set-key "1" 'select-window-1)
(evil-leader/set-key "2" 'select-window-2)
(evil-leader/set-key "3" 'select-window-3)
(evil-leader/set-key "4" 'select-window-4)
(evil-leader/set-key "5" 'select-window-5)
(evil-leader/set-key "6" 'select-window-6)
(evil-leader/set-key "7" 'select-window-7)
(evil-leader/set-key "8" 'select-window-8)
(evil-leader/set-key "9" 'select-window-9)
;; applications ---------------------------------------------------------------
(evil-leader/set-key "ae" 'erc-start-or-switch)
(evil-leader/set-key "am" 'mu4e-up-to-date-status)
Expand Down

0 comments on commit 0931e4a

Please sign in to comment.