feat!: switch to fork of winum for numbering windows

This commit is contained in:
Kiana Sheibani 2024-08-26 19:52:24 -04:00
parent 27801ea209
commit 7419450c9d
Signed by: toki
GPG key ID: 6CB106C25E86A9F7
2 changed files with 128 additions and 25 deletions

View file

@ -948,7 +948,6 @@ We'll also enable a dedicated spell checking module using ~aspell~, as that seem
Most of these are either defaults that come with Doom Emacs or just recommended, but here are the highlights:
- ~vi-tilde-fringe~ because I like how it looks
- ~(window-select +numbers)~ because multiple windows are too inconvenient without an easy way to switch between them
- ~file-templates~ and ~snippets~ because typing is hard
- ~(format +onsave)~ because I don't want to have to remember to run a formatter
- ~direnv~ because I'm a nix user
@ -977,7 +976,7 @@ ophints
unicode
(vc-gutter +pretty)
vi-tilde-fringe
(window-select +numbers)
;;(window-select +numbers)
workspaces
;;zen
#+end_src
@ -1196,30 +1195,9 @@ The =auth-source-pass= module lets you use [[*Password Management][pass]] as a s
#+call: confpkg()
*** Windows & Workspaces
*** Workspaces
I like using window numbers to navigate between splitscreen windows, but having to type =SPC w <#>= every time is annoying. Let's shorten that key sequence by 33%, and also throw in a convenient binding for switching to =treemacs=.
#+begin_src emacs-lisp
(map! :leader
;; Bind "SPC 0" to treemacs
;; Map window bindings to "SPC 1" through "SPC 9"
"w 0" #'treemacs-select-window
:desc "Select project tree window" "0" #'treemacs-select-window
:desc "Select window 1" "1" #'winum-select-window-1
:desc "Select window 2" "2" #'winum-select-window-2
:desc "Select window 3" "3" #'winum-select-window-3
:desc "Select window 4" "4" #'winum-select-window-4
:desc "Select window 5" "5" #'winum-select-window-5
:desc "Select window 6" "6" #'winum-select-window-6
:desc "Select window 7" "7" #'winum-select-window-7
:desc "Select window 8" "8" #'winum-select-window-8
:desc "Select window 9" "9" #'winum-select-window-9)
#+end_src
Now =SPC 1= will work equivalently to =SPC w 1=. Efficiency!
I like to reorganize my workspaces, so we can also add bindings to change the workspace order.
I like to reorganize my workspaces, so we can add bindings to change the workspace order.
#+begin_src emacs-lisp
(map! :leader
@ -1591,6 +1569,8 @@ Now that we've enabled our preferred modules and done some basic configuration,
corfu-min-width 25))
#+end_src
*** Omnicomplete Bindings
Before switching to Corfu, I got really used to Doom's omnicomplete bindings for various company backends. Doom unfortunately doesn't do this for CAPFs, so we'll have to do the work ourselves.
#+begin_src emacs-lisp
@ -1605,6 +1585,15 @@ Before switching to Corfu, I got really used to Doom's omnicomplete bindings for
:i "\\" #'cape-tex)
#+end_src
*** Window Numbers
Corfu's posframe buffer shouldn't be numbered by =winum=:
#+begin_src emacs-lisp
(after! (corfu winum)
(push " *corfu*" winum-ignored-buffers))
#+end_src
** Eldoc
#+call: confpkg("Pkg: eldoc")
@ -2398,6 +2387,119 @@ I've set my default Emacs shell to =bash=, since pointing Emacs to a non-POSIX s
(setq-default vterm-shell (executable-find "fish")))
#+end_src
** Window Numbering
#+call: confpkg("Pkg: winum")
Emacs comes with a few standard commands for selecting different windows. These are mostly directional, allowing you to move your selection up, right, left or down from the current window. This is rather inconvenient when working with large amounts of windows, so the =winum= package allows you to assign a number to each window to make navigation easier.
There's just one problem with =winum= for my purposes: Doom Emacs's popup management system. In Doom Emacs, popups are treated as separate from "real" windows, usually displayed on the edge of the frame and without a modeline. =winum= has no knowledge of popup windows, and assigns them numbers exactly the same as any other window, which is very confusing when popups are otherwise treated as separate.
To solve this issue, I've written my own fork of =winum=:
#+begin_src emacs-lisp :tangle packages.el
(package! winum :recipe (:local-repo "pkgs/winum"))
#+end_src
This fork generalizes the window numbering system to support indexing windows with any Lisp object, instead of just integers. We can then index regular windows with integers ~N~, and popup windows with cons cells ~(popup . N)~, allowing us to number them separately.
*** Configuration
#+begin_src emacs-lisp
(use-package! winum
:after-call doom-switch-window-hook
:config
(setq winum-auto-setup-mode-line nil)
(winum-mode +1)
(map! :map evil-window-map
"0" #'winum-select-window-0-or-10
"1" #'winum-select-window-1
"2" #'winum-select-window-2
"3" #'winum-select-window-3
"4" #'winum-select-window-4
"5" #'winum-select-window-5
"6" #'winum-select-window-6
"7" #'winum-select-window-7
"8" #'winum-select-window-8
"9" #'winum-select-window-9)
(map! :leader
:desc "Select window 1" "1" #'winum-select-window-1
:desc "Select window 2" "2" #'winum-select-window-2
:desc "Select window 3" "3" #'winum-select-window-3
:desc "Select window 4" "4" #'winum-select-window-4
:desc "Select window 5" "5" #'winum-select-window-5
:desc "Select window 6" "6" #'winum-select-window-6
:desc "Select window 7" "7" #'winum-select-window-7
:desc "Select window 8" "8" #'winum-select-window-8
:desc "Select window 9" "9" #'winum-select-window-9))
#+end_src
*** Popup Management
With the basic config out of the way, we can implement popup-aware numbering by changing the ~winum-auto-assign-function~.
#+begin_src emacs-lisp
(after! winum
(defun ~/winum-auto-assign (windows)
"Assign indices to windows, handling popup windows separately."
(let ((index 1) (popup-index 1))
(dolist (w windows)
(if (+popup-window-p w)
(progn
(while (member (cons 'popup popup-index)
winum--assigned-indices)
(setq popup-index (1+ popup-index)))
(winum--assign w (cons 'popup popup-index))
(setq popup-index (1+ popup-index)))
(while (member index winum--assigned-indices)
(setq index (1+ index)))
(winum--assign w index)
(setq index (1+ index))))))
(setq winum-auto-assign-function #'~/winum-auto-assign))
#+end_src
For convenience, we can add functions to select a particular popup window:
#+begin_src emacs-lisp
(map! :leader
"~" nil
:prefix ("~" . "popup")
:desc "Toggle last popup"
"~" #'+popup/toggle)
(dolist (n (number-sequence 1 9))
(let ((function (intern (format "+winum-select-popup-%s" n))))
(eval
`(progn
(defun ,function (&optional arg)
,(format "Jump to popup window %s.
If prefix ARG is given, delete the window instead of selecting it." n)
(interactive "P")
(if arg
(winum-delete-window-by-index '(popup . ,n))
(winum-select-window-by-index '(popup . ,n))))
(map! :leader
:desc ,(format "Select popup %s" n)
,(format "M-%s" n) #',function
:desc ,(format "Select popup %s" n)
,(format "~ %s" n) #',function)))))
(defun +winum-select-popup-0-or-10 (&optional arg)
"Jump to popup window 0, or popup 10 if 0 is not assigned.
If prefix ARG is given, delete the window instead of selecting it."
(interactive "P")
(let ((n (if (winum-get-window-by-index '(popup . 0)) '(popup . 0) '(popup . 10))))
(if arg
(winum-delete-window-by-index n)
(winum-select-window-by-index n))))
(map! :leader
:desc "Select popup 0 or 10"
"M-0" #'+winum-select-popup-0-or-10
:desc "Select popup 0 or 10"
"~ 0" #'+winum-select-popup-0-or-10)
#+end_src
* Applications
** Calculator

1
pkgs/winum Submodule

@ -0,0 +1 @@
Subproject commit aca0f74f3a442b1b1a6f4315303c340f7c1005b8