From bfef4ae6d0e0e5f1fb7e13e06298e4692e5b11a6 Mon Sep 17 00:00:00 2001 From: Alexander M Date: Sun, 28 May 2017 14:47:33 +0200 Subject: [PATCH] Use a list of functions for custom window number assignment --- README.org | 61 +++++++++++++++++++++++++++++------------------- winum.el | 68 ++++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 96 insertions(+), 33 deletions(-) diff --git a/README.org b/README.org index 0672251..135f6df 100644 --- a/README.org +++ b/README.org @@ -196,29 +196,40 @@ Several options are available through Emacs' Customize interface under Default: =t= -- =winum-assign-func= +- =winum-assign-functions= - Function called for each window by =winum-mode=. This is called before - automatic assignment begins. The function should return a number to have it - assigned to the current-window, =nil= otherwise. + List of functions called for each window by `winum-mode'. - This function along with `winum-auto-assign-0-to-minibuffer' are the only ways - to have 0 assigned to a window. + These functions allow for deterministic assignment of numbers to windows. Each + function is called for every window. A function should return the number to be + assigned to a window or nil. The /first/ function to output a number for + a given window will determine this window's number (if more than 1 function + assigns a number a warning will be logged in the messages buffer). + + If the list is empty or if every function returns nil for a given window winum + will proceed to automatic number assignment. + + Since this list is meant to allow custom window assignment for /mutiple/ + packages at once it should never be directly set, only added to and removed + from. + + These functions, along with ~winum-auto-assign-0-to-minibuffer~, are the only + way to have 0 assigned to a window. Example: always assign *Calculator* the number 9 and *NeoTree* the number 0: -#+BEGIN_SRC emacs-lisp - (defun my-winum-assign-func () - (cond - ((equal (buffer-name) "*Calculator*") - 9) - ((string-match-p (buffer-name) ".*\\*NeoTree\\*.*") - 0) - (t - nil))) + #+BEGIN_SRC emacs-lisp + (defun winum-assign-9-to-calculator-8-to-flycheck-errors () + (cond + ((equal (buffer-name) "*Calculator*") 9) + ((equal (buffer-name) "*Flycheck errors*") 8))) - (setq winum-assign-func 'my-winum-assign-func) -#+END_SRC + (defun winum-assign-0-to-neotree-and () + (when (string-match-p (buffer-name) ".*\\*NeoTree\\*.*") 10)) + + (add-to-list 'winum-assign-functions #'winum-assign-9-to-calculator-8-to-flycheck-errors) + (add-to-list 'winum-assign-functions #'winum-assign-0-to-neotree) + #+END_SRC Default: =nil= @@ -268,14 +279,16 @@ available winum options. (require 'winum) - (defun my-winum-assign-func () + (defun winum-assign-9-to-calculator-8-to-flycheck-errors () (cond - ((equal (buffer-name) "*Calculator*") - 9) - ((string-match-p (buffer-name) ".*\\*NeoTree\\*.*") - 0) - (t - nil))) + ((equal (buffer-name) "*Calculator*") 9) + ((equal (buffer-name) "*Flycheck errors*") 8))) + + (defun winum-assign-0-to-neotree-and () + (when (string-match-p (buffer-name) ".*\\*NeoTree\\*.*") 10)) + + (add-to-list 'winum-assign-functions #'winum-assign-9-to-calculator-8-to-flycheck-errors) + (add-to-list 'winum-assign-functions #'winum-assign-0-to-neotree) (set-face-attribute 'winum-face nil :weight 'bold) diff --git a/winum.el b/winum.el index f3fc5f7..65dfa1f 100644 --- a/winum.el +++ b/winum.el @@ -22,7 +22,7 @@ ;; URL: http://github.com/deb0ch/winum.el ;; Created: 2016 ;; Compatibility: GNU Emacs 24.x -;; Package-requires: ((cl-lib "0.5")) +;; Package-requires: ((cl-lib "0.5") (dash "2.13.0")) ;; ;; This file is NOT part of GNU Emacs. ;; @@ -43,6 +43,7 @@ ;; (eval-when-compile (require 'cl-lib)) +(require 'dash) ;; Configuration variables ----------------------------------------------------- @@ -92,6 +93,44 @@ Example: always assign *Calculator* the number 9 and *NeoTree* the number 0: :group 'winum :type 'function) +(make-obsolete-variable 'winum-assign-func 'winum-assign-functions "28.05.2017") + +(defcustom winum-assign-functions nil + "List of functions called for each window by `winum-mode'. + +These functions allow for deterministic assignment of numbers to windows. Each +function is called for every window. A function should return the number to be +assigned to a window or nil. The *first* function to output a number for +a given window will determine this window's number. + +If the list is empty or if every functions returns nil for a given window winum +will proceed to automatic number assignment. + +Since this list is meant to allow custom window assignment for *mutiple* +packages at once it should never be directly set, only added to and removed +from. + +These functions, along with `winum-auto-assign-0-to-minibuffer', are the only +way to have 0 assigned to a window. + +Example: always assign *Calculator* the number 9, *Flycheck-errors* the number 8 +and *NeoTree* the number 0: + + (defun winum-assign-9-to-calculator-8-to-flycheck-errors () + (cond + ((equal (buffer-name) \"*Calculator*\") 9) + ((equal (buffer-name) \"*Flycheck errors*\") 8))) + + (defun winum-assign-0-to-neotree () + (when (string-match-p (buffer-name) \".*\\*NeoTree\\*.*\") 10)) + + (add-to-list + 'winum-assign-functions #'winum-assign-9-to-calculator-8-to-flycheck-errors) + (add-to-list + 'winum-assign-functions #'winum-assign-0-to-neotree)" + :group 'winum + :type 'list) + (defcustom winum-auto-setup-mode-line t "When nil, `winum-mode' will not display window numbers in the mode-line. You might want this to be nil if you use a package that already manages window @@ -398,14 +437,8 @@ POSITION: position in the mode-line." winum--remaining (winum--available-numbers)) (winum--set-window-vector (make-vector (1+ winum--window-count) nil)) (clrhash (winum--get-numbers-table)) - (when winum-assign-func - (mapc (lambda (w) - (with-selected-window w - (with-current-buffer (window-buffer w) - (let ((num (funcall winum-assign-func))) - (when num - (winum--assign w num)))))) - windows)) + (when winum-assign-functions + (-each windows #'winum--try-to-find-custom-number)) (when (and winum-auto-assign-0-to-minibuffer (active-minibuffer-window) (not (winum-get-window-by-number 0))) @@ -413,6 +446,23 @@ POSITION: position in the mode-line." (dolist (w windows) (winum--assign w)))) +(defun winum--try-to-find-custom-number (window) + "Try to find and assign a custom number for WINDOW. +Do so by trying every function in `winum-assign-functions' and assign the +*first* non nil integer. +When multiple functions assign a number to a window log a warning and use the +first number anyway." + (with-selected-window window + (with-current-buffer (window-buffer window) + (let* ((nums (->> winum-assign-functions + (--map (cons it (funcall it))) + (--remove (null (cdr it))))) + (num (-> nums (cl-first) (cdr)))) + (when (> (length nums) 1) + (message "Winum conflict - window %s was assigned a number by multiple custom assign functions: '%s'" + window (--map (format "%s -> %s" (car it) (cdr it)) nums))) + (when (integerp num) (winum--assign window num)))))) + (defun winum--assign (window &optional number) "Assign to window WINDOW the number NUMBER. If NUMBER is not specified, determine it first based on `winum--remaining'.