| .gitignore | ||
| README.org | ||
| winum.el | ||
Window numbers for Emacs !
Introduction
This package is a fork of the winum package, which is itself a fork of the window-numbering package.
Compared to winum, this fork adds support for windows having arbitrary Lisp values as identifiers, as opposed to strictly increasing numbers. The public API is largely the same, however, and simple numbers are still the default.
Changelog
Jan. 26 2026
- Added support for changing how Lisp indices are displayed via
winum-display-function. - Removed
winum-mode-line-ppredicate.
Aug. 26 2024
- Added support for arbitrary Lisp objects (non-nil, compared with
equal) as indices. - Added customize variable
winum-auto-assign-functionto control auto-assigning behavior.
Sep. 11 2019
- Added customize variable
winum-ignored-buffers-regexpto ignored buffers based on regexps.
Nov. 15 2018
- Added customize variable
winum-format, a format string to configure how the window number appears in the mode-line
Initial release: what's changed since window-numbering
This package brings a lot of additions to the old window-numbering:
- Number sets across multiple frames, giving a smoother experience of multi-screen Emacs
- 3 possible scopes: frame-local, visible frames or all frames
get-window-by-numberpublic function, needed in Spacemacs and for future developments.- Unlimited window numbers
select-window-by-numbercan now be used interactively to select a window using prefix arg orread-from-minibuffer, allowing the selection of an unlimited number.- Ignore buffers by name
;;;###autoloadall functions that should have public visibility- Improved
customizeintegration - Removed
window-numbering-before-assign-hook, which just duplicatedwindow-numbering-assign-funcin a more complicated fashion - New default key bindings under the
C-x wprefix, to be compliant with Emacs key bindings conventions and native Emacs key bindings winum-set-keymap-prefixhelper function to change the prefix more easily- More detailed README.org
- Improved docstrings
- Simplified implementation for better readability
Installation
Using Melpa
The recommended way of installing winum is from the Melpa package repository:
M-x package-install RET winum RET
You will find instructions to setup Melpa here if you don't have it setup yet.
Once the package is installed, you need to load and activate winum-mode in
your Emacs configuration:
(require 'winum)
(winum-mode)
Manual installation
- Clone the repo:
cd /path/to/install/folder
git clone https://github.com/deb0ch/emacs-winum
- Add the following to your Emacs configuration:
(add-to-list 'load-path "/path/to/install/folder/emacs-winum/")
(require 'winum)
(winum-mode)
How to use
| Key binding | Description |
|---|---|
C-x w <n> |
select window <n>, where <n> ranges from 0 to 9. A negative argument deletes the window. |
C-x w ` |
select window by index. Integer indices can be given as prefix arg, or the index will be read from minibuffer. |
select-window-0-or-10By default,C-x w 0is bound toselect-window-0-or-10. If window 0 is not assigned, it will act on the window 10 instead. You can rebind this to the more straightforwardselect-window-0if you prefer.-
select-window-by-indexIf you happen to have more than 10 windows, or if you want to select a window that doesn't have an integer index, you can use the
select-window-by-indexfunction, bound by default toC-x w `.This function allows several ways to input the window number:
- Use a numbered prefix argument.
Ex:C-1 C-2 C-x w `to select window 12. - Use the default prefix argument to delete current window.
Ex:C-u C-x w `to delete current window. - If no prefix argument is given, an un-evaluated Lisp value is read from minibuffer.
- Use a numbered prefix argument.
Configuration
Keybindings
The default prefix for key bindings is C-x w for compatibility with native
Emacs bindings.
If you don't like C-x w, you can set a prefix of your choosing using the
function winum-set-keymap-prefix:
(winum-set-keymap-prefix (kbd "C-c"))
This function overrides the value of winum-keymap, so you should call it
before customization of winum-keymap and/or after customization of
winum-base-map. Its argument must be a key sequence, like the ones returned by
kbd.
If you prefer no to use a prefix and have even shorter bindings, you can also
override winum-keymap in the minor mode bindings table:
(setq winum-keymap
(let ((map (make-sparse-keymap)))
(define-key map (kbd "C-`") 'winum-select-window-by-index)
(define-key map (kbd "C-²") 'winum-select-window-by-index)
(define-key map (kbd "M-0") 'winum-select-window-0-or-10)
(define-key map (kbd "M-1") 'winum-select-window-1)
(define-key map (kbd "M-2") 'winum-select-window-2)
(define-key map (kbd "M-3") 'winum-select-window-3)
(define-key map (kbd "M-4") 'winum-select-window-4)
(define-key map (kbd "M-5") 'winum-select-window-5)
(define-key map (kbd "M-6") 'winum-select-window-6)
(define-key map (kbd "M-7") 'winum-select-window-7)
(define-key map (kbd "M-8") 'winum-select-window-8)
map))
(require 'winum)
(winum-mode)
Note that it is important to set winum-keymap before the require.
You can also use the more conventional define-key on winum-keymap:
(define-key winum-keymap (kbd "C-x y o l o") 'winum-select-window-by-index)
NB: Both ` and ² are mapped to winum-select-window-by-number by default
to handle both qwerty and azerty keyboard layouts. If you are using a
different kind of layout, the recommended place to map it is the key
beside 1.
Customize options
Several options are available through Emacs' Customize interface under
convenience > winum:
winum-scopeFrames affected by a number set. Choices are 'frame-local 'visible or 'global. Default: 'globalwinum-reverse-frame-listIf t, order frames by reverse order of creation. Has effect only whenwinum-scopeis not 'frame-local. Default:nilwinum-minibuffer-auto-assignIf non-nil,winum-modeautomatically assigns this index to the minibuffer. Default:0-
winum-assign-functionsList 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 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:
(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)Default:
nil winum-auto-assign-functionThe function called to auto-assign indices to windows. This function is called afterwinum-assign-functionsto automatically assign indices to the remaining windows. It must take in a list of windows and call the functionwinum--assignto assign an index to each, while avoiding assigning any indices already taken (stored inwinum--assigned-indices). Members of this list should be tested for using `equal'. Default:#'winum--auto-assignwinum-auto-setup-mode-lineWhen nil,winum-modewill not display window numbers in the mode-line. You might want this to be nil if you use a package that already manages window numbers in the mode-line. Default:twinum-formatFormat string defining how the window number looks like in the mode-line. This string is passed to theformatfunction along with the result ofwinum-get-number-string. Default:" %s "winum-mode-line-positionThe position in the mode-linewinum-modedisplays the number. Default:1winum-ignored-buffersList of buffers to ignore when assigning numbers. Default: '(" which-key")winum-ignored-buffers-regexpList of regexps for buffer names. Matching buffers will be ignored when assigning numbers. See Emacs' documentation on regexps for syntax. Default: '()- face:
winum-faceFace used for the number in the mode-line.
Configuration file example
Here is an example that you could put in your .emacs, which includes all
available winum options.
(setq winum-keymap
(let ((map (make-sparse-keymap)))
(define-key map (kbd "C-`") 'winum-select-window-by-index)
(define-key map (kbd "C-²") 'winum-select-window-by-index)
(define-key map (kbd "M-0") 'winum-select-window-0-or-10)
(define-key map (kbd "M-1") 'winum-select-window-1)
(define-key map (kbd "M-2") 'winum-select-window-2)
(define-key map (kbd "M-3") 'winum-select-window-3)
(define-key map (kbd "M-4") 'winum-select-window-4)
(define-key map (kbd "M-5") 'winum-select-window-5)
(define-key map (kbd "M-6") 'winum-select-window-6)
(define-key map (kbd "M-7") 'winum-select-window-7)
(define-key map (kbd "M-8") 'winum-select-window-8)
map))
(require 'winum)
(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)
(set-face-attribute 'winum-face nil :weight 'bold)
(setq window-numbering-scope 'global
winum-reverse-frame-list nil
winum-minibuffer-auto-assign 0
winum-assign-func 'my-winum-assign-func
winum-auto-setup-mode-line t
winum-format " %s "
winum-mode-line-position 1
winum-ignored-buffers '(" *which-key*")
winum-ignored-buffers-regexp '(" \\*Treemacs-.*"))
(winum-mode)
Future developments
- send buffer to numbered window Send current window's buffer to window N. With prefix argument focus will follow.
- swap buffer with numbered window Same as previous, but will swap buffers instead of just sending them.
- Evilify Adapt the package to the famous `evil-mode` and use a leader key.
- Override native
other-window(C-x o) to use window numbers - Autocomplete read-from-minibuffer
- Things that you have thought of and I haven't 😸