diff --git a/winum.el b/winum.el index 3e13e0e..5ef6070 100644 --- a/winum.el +++ b/winum.el @@ -128,9 +128,11 @@ and *NeoTree* the number 0: This function is called after `winum-assign-functions' to automatically assign indices to the remaining windows. It must take in a list of windows and call -the function `winum--assign' to assign an index to each, while avoiding -assigning any indices already taken (stored in `winum--assigned-indices'). -Members of this list should be tested for using `equal'. +the function `winum--assign' to assign an index to each. + +Auto-assign functions must not assign any indices that are `equal' to an index +already used (stored in `winum--assigned-indices'). The convenience macro +`winum--assign-unique' will handle this automatically. The default auto-assign function is `winum--auto-assign', which assigns strictly increasing integers to each window." @@ -505,16 +507,40 @@ POSITION: position in the mode-line." (when windows (funcall winum-auto-assign-function windows)))) +(defmacro winum--assign-unique (window var &optional after update pred) + "Ensure that the index in VAR is unique, then assign it to WINDOW. + +If AFTER is non-nil, also ensure that VAR is unique after the assignment. + +UPDATE and PRED are quoted function symbols or unquoted sexps. If they +are functions, then the value of VAR is passed as input. +UPDATE must return a new index to be assigned to VAR, with the guarantee +that repeatedly executing it will never return the same index twice. The +default updating function is `1+'. +PRED must be non-nil if VAR must be updated. By default, PRED checks if +the variable's value is in `winum--assigned-indices'." + (unless pred + (setq pred `(member ,var winum--assigned-indices))) + (unless update + (setq update '#'1+)) + (and (= (safe-length pred) 2) + (memq (car pred) '(quote function)) + (setq pred `(funcall ,pred ,var))) + (and (= (safe-length update) 2) + (memq (car update) '(quote function)) + (setq update `(funcall ,update ,var))) + `(progn + (while ,pred (setq ,var ,update)) + (winum--assign ,window ,var) + ,@(and after `((setq ,var ,update))))) + (defun winum--auto-assign (windows) "The default auto-assign function for assigning indices to windows. Takes in the list of windows WINDOWS and uses `winum--assign' to assign increasing integers to it." (let ((index 1)) (dolist (w windows) - (while (member index winum--assigned-indices) - (setq index (1+ index))) - (winum--assign w index) - (setq index (1+ index))))) + (winum--assign-unique w index t)))) (defun winum--try-to-find-custom-index (window) "Try to find and assign a custom index for WINDOW.