Personal emacs config
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

630 lines
23 KiB

  1. ;;; winum.el --- Navigate windows and frames using numbers.
  2. ;;
  3. ;; Copyright (c) 2006-2015 Nikolaj Schumacher
  4. ;; Copyright (c) 2016 Thomas Chauvot de Beauchêne
  5. ;;
  6. ;; This program is free software: you can redistribute it and/or modify
  7. ;; it under the terms of the GNU General Public License as published by
  8. ;; the Free Software Foundation, either version 3 of the License, or
  9. ;; (at your option) any later version.
  10. ;;
  11. ;; This program is distributed in the hope that it will be useful,
  12. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. ;; GNU General Public License for more details.
  15. ;;
  16. ;; You should have received a copy of the GNU General Public License
  17. ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. ;;
  19. ;; Author: Thomas de Beauchêne <thomas.de.beauchene@gmail.com>
  20. ;; Version: 2.1.0
  21. ;; Package-Version: 2.1.0
  22. ;; Package-Commit: efcb14fd306afbc738666e6b2e5a8a1bb5904392
  23. ;; Keywords: convenience, frames, windows, multi-screen
  24. ;; URL: http://github.com/deb0ch/winum.el
  25. ;; Created: 2016
  26. ;; Compatibility: GNU Emacs 24.x
  27. ;; Package-requires: ((cl-lib "0.5") (dash "2.13.0"))
  28. ;;
  29. ;; This file is NOT part of GNU Emacs.
  30. ;;
  31. ;;; Commentary:
  32. ;;
  33. ;; Window numbers for Emacs: Navigate your windows and frames using numbers.
  34. ;;
  35. ;; This package is an extended and actively maintained version of the
  36. ;; https://github.com/nschum/window-numbering.el package by Nikolaj Schumacher,
  37. ;; with some ideas and code taken from https://github.com/abo-abo/ace-window.
  38. ;;
  39. ;; This version brings, among other things, support for number sets across multiple
  40. ;; frames, giving the user a smoother experience of multi-screen Emacs.
  41. ;;
  42. ;;; Code:
  43. ;;
  44. ;; FIXME: The mode-line's window number is not always up to date in all frames.
  45. ;;
  46. (eval-when-compile (require 'cl-lib))
  47. (require 'dash)
  48. ;; Configuration variables -----------------------------------------------------
  49. (defgroup winum nil
  50. "Navigate and manage windows using numbers."
  51. :group 'convenience)
  52. (defcustom winum-scope 'global
  53. "Frames affected by a number set."
  54. :group 'winum
  55. :type '(choice
  56. (const :tag "frame local" frame-local)
  57. (const :tag "visible frames" visible)
  58. (const :tag "global" global)))
  59. (defcustom winum-reverse-frame-list nil
  60. "If t, order frames by reverse order of creation.
  61. Has effect only when `winum-scope' is not 'frame-local."
  62. :group 'winum
  63. :type 'boolean)
  64. (defcustom winum-auto-assign-0-to-minibuffer t
  65. "If non-nil, `winum-mode' assigns 0 to the minibuffer when active."
  66. :group 'winum
  67. :type 'boolean)
  68. (defcustom winum-assign-func nil
  69. "Function called for each window by `winum-mode'.
  70. This is called before automatic assignment begins. The function should
  71. return a number to have it assigned to the current-window, nil otherwise.
  72. This function along with `winum-auto-assign-0-to-minibuffer' are the only
  73. ways to have 0 assigned to a window.
  74. Example: always assign *Calculator* the number 9 and *NeoTree* the number 0:
  75. (defun my-winum-assign-func ()
  76. (cond
  77. ((equal (buffer-name) \"*Calculator*\")
  78. 9)
  79. ((string-match-p (buffer-name) \".*\\*NeoTree\\*.*\")
  80. 0)
  81. (t
  82. nil)))
  83. (setq winum-assign-func 'my-winum-assign-func)"
  84. :group 'winum
  85. :type 'function)
  86. (make-obsolete-variable 'winum-assign-func 'winum-assign-functions "2.0.0")
  87. (defcustom winum-assign-functions nil
  88. "List of functions called for each window by `winum-mode'.
  89. These functions allow for deterministic assignment of numbers to windows. Each
  90. function is called for every window. A function should return the number to be
  91. assigned to a window or nil. The *first* function to output a number for
  92. a given window will determine this window's number.
  93. If the list is empty or if every functions returns nil for a given window winum
  94. will proceed to automatic number assignment.
  95. Since this list is meant to allow custom window assignment for *mutiple*
  96. packages at once it should never be directly set, only added to and removed
  97. from.
  98. These functions, along with `winum-auto-assign-0-to-minibuffer', are the only
  99. way to have 0 assigned to a window.
  100. Example: always assign *Calculator* the number 9, *Flycheck-errors* the number 8
  101. and *NeoTree* the number 0:
  102. (defun winum-assign-9-to-calculator-8-to-flycheck-errors ()
  103. (cond
  104. ((equal (buffer-name) \"*Calculator*\") 9)
  105. ((equal (buffer-name) \"*Flycheck errors*\") 8)))
  106. (defun winum-assign-0-to-neotree ()
  107. (when (string-match-p (buffer-name) \".*\\*NeoTree\\*.*\") 10))
  108. (add-to-list
  109. 'winum-assign-functions #'winum-assign-9-to-calculator-8-to-flycheck-errors)
  110. (add-to-list
  111. 'winum-assign-functions #'winum-assign-0-to-neotree)"
  112. :group 'winum
  113. :type 'list)
  114. (defcustom winum-auto-setup-mode-line t
  115. "When nil, `winum-mode' will not display window numbers in the mode-line.
  116. You might want this to be nil if you use a package that already manages window
  117. numbers in the mode-line."
  118. :group 'winum
  119. :type 'boolean)
  120. (defcustom winum-mode-line-position 1
  121. "The position in the mode-line `winum-mode' displays the number."
  122. :group 'winum
  123. :type 'integer)
  124. (defcustom winum-format " %s "
  125. "Format string defining how the window number looks like in the mode-line.
  126. This string is passed to the `format' function along with the
  127. result of `winum-get-number-string'."
  128. :group 'winum
  129. :type 'string)
  130. (defcustom winum-ignored-buffers '(" *which-key*")
  131. "List of buffers to ignore when assigning numbers."
  132. :group 'winum
  133. :type '(repeat string))
  134. (defface winum-face '()
  135. "Face used for the number in the mode-line."
  136. :group 'winum)
  137. (defvar winum-base-map
  138. (let ((map (make-sparse-keymap)))
  139. (define-key map (kbd "`") 'winum-select-window-by-number)
  140. (define-key map (kbd "²") 'winum-select-window-by-number)
  141. (define-key map (kbd "0") 'winum-select-window-0-or-10)
  142. (define-key map (kbd "1") 'winum-select-window-1)
  143. (define-key map (kbd "2") 'winum-select-window-2)
  144. (define-key map (kbd "3") 'winum-select-window-3)
  145. (define-key map (kbd "4") 'winum-select-window-4)
  146. (define-key map (kbd "5") 'winum-select-window-5)
  147. (define-key map (kbd "6") 'winum-select-window-6)
  148. (define-key map (kbd "7") 'winum-select-window-7)
  149. (define-key map (kbd "8") 'winum-select-window-8)
  150. (define-key map (kbd "9") 'winum-select-window-9)
  151. map)
  152. "Keymap to be used under the prefix provided by `winum-keymap-prefix'.")
  153. (defvar winum-keymap (let ((map (make-sparse-keymap)))
  154. (define-key map (kbd "C-x w") winum-base-map)
  155. map)
  156. "Keymap used for `winum-mode'.")
  157. ;; Internal variables ----------------------------------------------------------
  158. (defvar winum--max-frames 16
  159. "Maximum number of frames that can be numbered.")
  160. (defvar winum--window-count nil
  161. "Current count of windows to be numbered.")
  162. (defvar winum--remaining nil
  163. "A list of window numbers to assign.")
  164. (defvar winum--window-vector nil
  165. "Vector of windows indexed by their number.
  166. Used internally by winum to get a window provided a number.")
  167. (defvar winum--numbers-table nil
  168. "Hash table of numbers indexed by their window.
  169. Used internally by winum to get a number provided a window.")
  170. (defvar winum--frames-table nil
  171. "Table linking windows to numbers and numbers to windows for each frame.
  172. Used only when `winum-scope' is 'frame-local to keep track of
  173. separate window numbers sets in every frame.
  174. It is a hash table using Emacs frames as keys and cons of the form
  175. \(`winum--window-vector' . `winum--numbers-table')
  176. as values.
  177. To get a window given a number, use the `car' of a value.
  178. To get a number given a window, use the `cdr' of a value.
  179. Such a structure allows for per-frame bidirectional fast access.")
  180. (defvar winum--mode-line-segment
  181. '(:eval (format winum-format (winum-get-number-string)))
  182. "What is pushed into `mode-line-format' when setting it up automatically.")
  183. (defvar winum--last-used-scope winum-scope
  184. "Tracks the last used `winum-scope'.
  185. Needed to detect scope changes at runtime.")
  186. ;; Interactive functions -------------------------------------------------------
  187. ;;;###autoload
  188. (define-minor-mode winum-mode
  189. "A minor mode that allows for managing windows based on window numbers."
  190. nil
  191. nil
  192. winum-keymap
  193. :global t
  194. (if winum-mode
  195. (winum--init)
  196. (winum--deinit)))
  197. ;;;###autoload
  198. (defun winum-select-window-0-or-10 (&optional arg)
  199. "Jump to window 0 if assigned or 10 if exists.
  200. If prefix ARG is given, delete the window instead of selecting it."
  201. (interactive "P")
  202. (let ((n (if (winum-get-window-by-number 0)
  203. (if arg '- 0)
  204. (if arg -10 10))))
  205. (winum-select-window-by-number n)))
  206. ;;;###autoload
  207. (defun winum-select-window-0 (&optional arg)
  208. "Jump to window 0.
  209. If prefix ARG is given, delete the window instead of selecting it."
  210. (interactive "P")
  211. (winum-select-window-by-number (if arg '- 0)))
  212. ;;;###autoload
  213. (defun winum-select-window-1 (&optional arg)
  214. "Jump to window 1.
  215. If prefix ARG is given, delete the window instead of selecting it."
  216. (interactive "P")
  217. (winum-select-window-by-number (if arg -1 1)))
  218. ;;;###autoload
  219. (defun winum-select-window-2 (&optional arg)
  220. "Jump to window 2.
  221. If prefix ARG is given, delete the window instead of selecting it."
  222. (interactive "P")
  223. (winum-select-window-by-number (if arg -2 2)))
  224. ;;;###autoload
  225. (defun winum-select-window-3 (&optional arg)
  226. "Jump to window 3.
  227. If prefix ARG is given, delete the window instead of selecting it."
  228. (interactive "P")
  229. (winum-select-window-by-number (if arg -3 3)))
  230. ;;;###autoload
  231. (defun winum-select-window-4 (&optional arg)
  232. "Jump to window 4.
  233. If prefix ARG is given, delete the window instead of selecting it."
  234. (interactive "P")
  235. (winum-select-window-by-number (if arg -4 4)))
  236. ;;;###autoload
  237. (defun winum-select-window-5 (&optional arg)
  238. "Jump to window 5.
  239. If prefix ARG is given, delete the window instead of selecting it."
  240. (interactive "P")
  241. (winum-select-window-by-number (if arg -5 5)))
  242. ;;;###autoload
  243. (defun winum-select-window-6 (&optional arg)
  244. "Jump to window 6.
  245. If prefix ARG is given, delete the window instead of selecting it."
  246. (interactive "P")
  247. (winum-select-window-by-number (if arg -6 6)))
  248. ;;;###autoload
  249. (defun winum-select-window-7 (&optional arg)
  250. "Jump to window 7.
  251. If prefix ARG is given, delete the window instead of selecting it."
  252. (interactive "P")
  253. (winum-select-window-by-number (if arg -7 7)))
  254. ;;;###autoload
  255. (defun winum-select-window-8 (&optional arg)
  256. "Jump to window 8.
  257. If prefix ARG is given, delete the window instead of selecting it."
  258. (interactive "P")
  259. (winum-select-window-by-number (if arg -8 8)))
  260. ;;;###autoload
  261. (defun winum-select-window-9 (&optional arg)
  262. "Jump to window 9.
  263. If prefix ARG is given, delete the window instead of selecting it."
  264. (interactive "P")
  265. (winum-select-window-by-number (if arg -9 9)))
  266. ;;;###autoload
  267. (defun winum-select-window-by-number (&optional arg)
  268. "Select or delete window which number is specified by ARG.
  269. If the number is negative, delete the window instead of selecting it.
  270. There are several ways to provide the number:
  271. - if called from elisp with an argument, use it.
  272. - if called interactively with a numeric prefix argument, use it.
  273. - if prefix argument is the negative argument, delete window 0.
  274. - if prefix argument is the default prefix argument, delete current window.
  275. - if called interactively and no valid argument is provided, read from
  276. minibuffer."
  277. (interactive "P")
  278. (let* ((n (cond
  279. ((integerp arg) arg)
  280. ((eq arg '-) 0) ; the negative argument
  281. (arg (winum-get-number))
  282. ((called-interactively-p 'any)
  283. (let ((user-input-str (read-from-minibuffer "Window: ")))
  284. (if (not (string-match-p "[+-]?[0-9]+\.*" user-input-str))
  285. (winum-get-number)
  286. (string-to-number user-input-str))))
  287. (t (winum-get-number))))
  288. (w (winum-get-window-by-number (abs n)))
  289. (delete (and arg
  290. (or (not (integerp arg))
  291. (> 0 n)))))
  292. (if w
  293. (if delete
  294. (delete-window w)
  295. (winum--switch-to-window w))
  296. (error "No window numbered %d" n))))
  297. ;; Public API ------------------------------------------------------------------
  298. ;;;###autoload
  299. (defun winum-set-keymap-prefix (prefix)
  300. "Set key bindings prefix for `winum-keymap' based on `winum-base-map'.
  301. This function overrides the value of `winum-keymap', so you
  302. should call it before customization of `winum-keymap' and/or
  303. after customization of `winum-base-map'.
  304. PREFIX must be a key sequence, like the ones returned by `kbd'."
  305. (setq winum-keymap (when prefix (let ((map (make-sparse-keymap)))
  306. (define-key map prefix winum-base-map)
  307. map)))
  308. (setcdr (assoc 'winum-mode minor-mode-map-alist)
  309. winum-keymap))
  310. ;;;###autoload
  311. (defun winum-get-window-by-number (n)
  312. "Return window numbered N if exists, nil otherwise."
  313. (let ((window-vector (winum--get-window-vector)))
  314. (when (and (>= n 0) (< n (length window-vector)))
  315. (aref window-vector n))))
  316. ;;;###autoload
  317. (defun winum-get-number-string (&optional window)
  318. "Get the current or specified window's current number as a propertized string.
  319. WINDOW: if specified, the window of which we want to know the number.
  320. If not specified, the number of the currently selected window is
  321. returned."
  322. (let* ((n (winum-get-number window))
  323. (s (if (numberp n)
  324. (int-to-string n)
  325. "")))
  326. (propertize s 'face 'winum-face)))
  327. ;;;###autoload
  328. (defun winum-get-number (&optional window)
  329. "Get the current or specified window's current number.
  330. WINDOW: if specified, the window of which we want to know the number.
  331. If not specified, the number of the currently selected window is
  332. returned."
  333. (let ((w (or window (selected-window))))
  334. (gethash w (winum--get-numbers-table))))
  335. ;; Internal functions ----------------------------------------------------------
  336. (defun winum--init ()
  337. "Initialize winum-mode."
  338. (setq winum--window-count (length (winum--window-list)))
  339. (if (eq winum-scope 'frame-local)
  340. (setq winum--frames-table (make-hash-table :size winum--max-frames))
  341. (setq winum--numbers-table (make-hash-table :size winum--window-count)))
  342. (when winum-auto-setup-mode-line
  343. (winum--install-mode-line))
  344. (add-hook 'minibuffer-setup-hook 'winum--update)
  345. (add-hook 'window-configuration-change-hook 'winum--update)
  346. (dolist (frame (frame-list))
  347. (select-frame frame)
  348. (winum--update)))
  349. (defun winum--deinit ()
  350. "Actions performed when turning off winum-mode."
  351. (when winum-auto-setup-mode-line
  352. (winum--clear-mode-line))
  353. (remove-hook 'minibuffer-setup-hook 'winum--update)
  354. (remove-hook 'window-configuration-change-hook 'winum--update)
  355. (setq winum--frames-table nil))
  356. (defun winum--install-mode-line (&optional position)
  357. "Install the window number from `winum-mode' to the mode-line.
  358. POSITION: position in the mode-line."
  359. (let ((mode-line (default-value 'mode-line-format))
  360. res)
  361. (dotimes (i (min (or position winum-mode-line-position 1)
  362. (length mode-line)))
  363. (push (pop mode-line) res))
  364. (unless (equal (car mode-line) winum--mode-line-segment)
  365. (push winum--mode-line-segment res))
  366. (while mode-line
  367. (push (pop mode-line) res))
  368. (let ((nres (nreverse res)))
  369. (setq mode-line-format nres)
  370. (setq-default mode-line-format nres)))
  371. (force-mode-line-update t))
  372. (defun winum--clear-mode-line ()
  373. "Remove the window number of `winum-mode' from the mode-line."
  374. (let ((mode-line (default-value 'mode-line-format))
  375. res)
  376. (while mode-line
  377. (let ((item (pop mode-line)))
  378. (unless (equal item winum--mode-line-segment)
  379. (push item res))))
  380. (let ((nres (nreverse res)))
  381. (setq mode-line-format nres)
  382. (setq-default mode-line-format nres)))
  383. (force-mode-line-update t))
  384. (defun winum--update ()
  385. "Update window numbers."
  386. (let ((windows (winum--window-list)))
  387. (setq winum--window-count (length windows)
  388. winum--remaining (winum--available-numbers))
  389. (winum--set-window-vector (make-vector (1+ winum--window-count) nil))
  390. (clrhash (winum--get-numbers-table))
  391. (when winum-assign-functions
  392. (-each windows #'winum--try-to-find-custom-number))
  393. (when (and winum-auto-assign-0-to-minibuffer
  394. (active-minibuffer-window)
  395. (not (winum-get-window-by-number 0)))
  396. (winum--assign (active-minibuffer-window) 0))
  397. (dolist (w windows)
  398. (winum--assign w))))
  399. (defun winum--try-to-find-custom-number (window)
  400. "Try to find and assign a custom number for WINDOW.
  401. Do so by trying every function in `winum-assign-functions' and assign the
  402. *first* non nil integer.
  403. When multiple functions assign a number to a window log a warning and use the
  404. first number anyway."
  405. (with-selected-window window
  406. (with-current-buffer (window-buffer window)
  407. (let* ((nums (->> winum-assign-functions
  408. (--map (cons it (funcall it)))
  409. (--remove (null (cdr it)))))
  410. (num (-> nums (cl-first) (cdr))))
  411. (when (> (length nums) 1)
  412. (message "Winum conflict - window %s was assigned a number by multiple custom assign functions: '%s'"
  413. window (--map (format "%s -> %s" (car it) (cdr it)) nums)))
  414. (when (integerp num) (winum--assign window num))))))
  415. (defun winum--assign (window &optional number)
  416. "Assign to window WINDOW the number NUMBER.
  417. If NUMBER is not specified, determine it first based on `winum--remaining'.
  418. Returns the assigned number, or nil on error."
  419. (if number
  420. (progn
  421. (winum--maybe-expand-window-vector number)
  422. (if (aref (winum--get-window-vector) number)
  423. (progn
  424. (message "Number %s already assigned to %s, can't assign to %s"
  425. number (aref (winum--get-window-vector) number) window)
  426. nil)
  427. (setf (aref (winum--get-window-vector) number) window)
  428. (puthash window number (winum--get-numbers-table))
  429. (setq winum--remaining (delq number winum--remaining))
  430. number))
  431. ;; else determine number and assign
  432. (when winum--remaining
  433. (unless (gethash window (winum--get-numbers-table))
  434. (let ((number (car winum--remaining)))
  435. (winum--assign window number))))))
  436. (defun winum--maybe-expand-window-vector (number)
  437. "Expand `winum--window-vector' if NUMBER is bigger than its size.
  438. The size of `winum--window-vector' is normally based on the number of live
  439. windows, however a higher number can be reserved by the user-defined
  440. `winum-assign-func'."
  441. (let* ((window-vector (winum--get-window-vector))
  442. (window-vector-length (length window-vector)))
  443. (when (> number window-vector-length)
  444. (winum--set-window-vector
  445. (vconcat window-vector
  446. (make-vector (1+ (- number window-vector-length)) nil))))))
  447. (defun winum--window-list ()
  448. "Return a list of interesting windows."
  449. (cl-remove-if
  450. #'winum--ignore-window-p
  451. (cl-case winum-scope
  452. (global
  453. (cl-mapcan 'winum--list-windows-in-frame
  454. (if winum-reverse-frame-list
  455. (frame-list)
  456. (nreverse (frame-list)))))
  457. (visible
  458. (cl-mapcan 'winum--list-windows-in-frame
  459. (if winum-reverse-frame-list
  460. (visible-frame-list)
  461. (nreverse (visible-frame-list)))))
  462. (frame-local
  463. (winum--list-windows-in-frame))
  464. (t
  465. (error "Invalid `winum-scope': %S" winum-scope)))))
  466. (defun winum--ignore-window-p (window)
  467. "Non-nil if WINDOW should be ignored for numbering."
  468. (let ((f (window-frame window)))
  469. (or (not (and (frame-live-p f)
  470. (frame-visible-p f)))
  471. (string= "initial_terminal" (terminal-name f))
  472. (member (buffer-name (window-buffer window)) winum-ignored-buffers))))
  473. (defun winum--list-windows-in-frame (&optional f)
  474. "List windows in frame F using natural Emacs ordering."
  475. (window-list f 0 (frame-first-window f)))
  476. (defun winum--set-window-vector (window-vector)
  477. "Set WINDOW-VECTOR according to the current `winum-scope'."
  478. (winum--check-for-scope-change)
  479. (if (eq winum-scope 'frame-local)
  480. (puthash (selected-frame)
  481. (cons window-vector
  482. (make-hash-table :size winum--window-count))
  483. winum--frames-table)
  484. (setq winum--window-vector window-vector)))
  485. (defun winum--get-window-vector ()
  486. "Return the window vector used to get a window given a number.
  487. This vector is not stored the same way depending on the value of `winum-scope'."
  488. (winum--check-for-scope-change)
  489. (if (eq winum-scope 'frame-local)
  490. (car (gethash (selected-frame) winum--frames-table))
  491. winum--window-vector))
  492. (defun winum--get-numbers-table ()
  493. "Return the numbers hashtable used to get a number given a window.
  494. This hashtable is not stored the same way depending on the value of
  495. `winum-scope'"
  496. (winum--check-for-scope-change)
  497. (winum--check-frames-table)
  498. (if (eq winum-scope 'frame-local)
  499. (cdr (gethash (selected-frame) winum--frames-table))
  500. winum--numbers-table))
  501. (defun winum--check-frames-table ()
  502. "Make sure `winum--frames-table' exists and is correctly equipped.
  503. Verifies 2 things (when `winum-scope' is frame local):
  504. * When `winum-scope' is frame-local for the first time it may be necessary to
  505. instantiate `winum--frames-table'.
  506. * A table entry for the current frame must be made when the frame has just
  507. been created."
  508. (when (eq winum-scope 'frame-local)
  509. (unless winum--frames-table
  510. (setq winum--frames-table (make-hash-table :size winum--max-frames)))
  511. (unless (gethash (selected-frame) winum--frames-table)
  512. (winum--update))))
  513. (defun winum--available-numbers ()
  514. "Return a list of numbers from 1 to `winum--window-count'.
  515. 0 is is not part of the list as its assignment is either manual
  516. using the `winum-assign-func', or using `winum-auto-assign-0-to-minibuffer'."
  517. (let ((numbers))
  518. (dotimes (i winum--window-count)
  519. (push (1+ i) numbers))
  520. (nreverse numbers)))
  521. (defun winum--switch-to-window (window)
  522. "Switch to the window WINDOW and switch input focus if on a different frame."
  523. (let ((frame (window-frame window)))
  524. (when (and (frame-live-p frame)
  525. (not (eq frame (selected-frame))))
  526. (select-frame-set-input-focus frame))
  527. (if (window-live-p window)
  528. (select-window window)
  529. (error "Got a dead window %S" window))))
  530. (defun winum--check-for-scope-change ()
  531. "Check whether the `winum-scope' has been changed.
  532. If a change is detected run `winum--init' to reinitialize all
  533. internal data structures according to the new scope."
  534. (unless (eq winum-scope winum--last-used-scope)
  535. (setq winum--last-used-scope winum-scope)
  536. (winum--init)))
  537. (defun winum--remove-deleted-frame-from-frames-table (frame)
  538. "Remove FRAME from `winum--frames-table' after it was deleted."
  539. (when winum--frames-table
  540. (remhash frame winum--frames-table)))
  541. (add-hook 'delete-frame-functions #'winum--remove-deleted-frame-from-frames-table)
  542. (push "^No window numbered .$" debug-ignored-errors)
  543. (push "^Got a dead window .$" debug-ignored-errors)
  544. (push "^Invalid `winum-scope': .$" debug-ignored-errors)
  545. (provide 'winum)
  546. ;;; winum.el ends here