From 293ca3fe5e00e241f5597f930893e0699004b81c Mon Sep 17 00:00:00 2001 From: Daniel Weschke Date: Tue, 25 Nov 2025 20:11:44 +0100 Subject: [PATCH] update packages, fix --- lisp/awesome-tray/awesome-tray-autoloads.el | 1 + lisp/cond-let/cond-let-pkg.el | 8 + lisp/cond-let/cond-let.el | 534 ++++++++++++++++++++ lisp/nerd-icons/nerd-icons-pkg.el | 6 +- lisp/nerd-icons/nerd-icons.el | 43 +- 5 files changed, 569 insertions(+), 23 deletions(-) create mode 100644 lisp/cond-let/cond-let-pkg.el create mode 100644 lisp/cond-let/cond-let.el diff --git a/lisp/awesome-tray/awesome-tray-autoloads.el b/lisp/awesome-tray/awesome-tray-autoloads.el index 098a97c2..82d01777 100644 --- a/lisp/awesome-tray/awesome-tray-autoloads.el +++ b/lisp/awesome-tray/awesome-tray-autoloads.el @@ -42,6 +42,7 @@ Turn on the awesome-tray." t) (autoload 'awesome-tray-disable "awesome-tray" "\ Turn off the awesome-tray." t) (register-definition-prefixes "awesome-tray" '("awesome-tray-")) + ;;; End of scraped data diff --git a/lisp/cond-let/cond-let-pkg.el b/lisp/cond-let/cond-let-pkg.el new file mode 100644 index 00000000..82aeaf1c --- /dev/null +++ b/lisp/cond-let/cond-let-pkg.el @@ -0,0 +1,8 @@ +;; -*- no-byte-compile: t; lexical-binding: nil -*- +(define-package "cond-let" "20251101.1942" + "Additional and improved binding conditionals." + '((emacs "28.1")) + :url "https://github.com/tarsius/cond-let" + :commit "288b7d36563223ebaf64cb220a3b270bdffb63f1" + :revdesc "288b7d365632" + :keywords '("extensions")) diff --git a/lisp/cond-let/cond-let.el b/lisp/cond-let/cond-let.el new file mode 100644 index 00000000..4c0b417d --- /dev/null +++ b/lisp/cond-let/cond-let.el @@ -0,0 +1,534 @@ +;;; cond-let.el --- Additional and improved binding conditionals -*- lexical-binding:t -*- + +;; Copyright (C) 2025 Jonas Bernoulli + +;; May contain traces of Emacs, which is +;; Copyright (C) 1985-2025 Free Software Foundation, Inc. + +;; Authors: Jonas Bernoulli +;; Homepage: https://github.com/tarsius/cond-let +;; Keywords: extensions + +;; Package-Version: 20251101.1942 +;; Package-Revision: 288b7d365632 +;; Package-Requires: ((emacs "28.1")) + +;; SPDX-License-Identifier: GPL-3.0-or-later + +;; This file is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published +;; by the Free Software Foundation, either version 3 of the License, +;; or (at your option) any later version. +;; +;; This file is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with this file. If not, see . + +;;; Commentary: + +;; This is an ALPHA release! +;; Breaking changes are possible! + +;; Emacs provides the binding conditionals `if-let', `if-let*', +;; `when-let', `when-let*', `and-let*' and `while-let'. + +;; This package implements the missing `and-let' and `while-let*', +;; and the original `cond-let', `cond-let*', `and$' and `and>'. + +;; This package additionally provides more consistent and improved +;; implementations of the binding conditionals already provided by +;; Emacs. Merely loading this library does not shadow the built-in +;; implementations; this can optionally be done in the context of +;; an individual library, as described below. + +;; `cond-let' and `cond-let*' are provided exactly under these names. +;; The names of all other macros implemented by this package begin +;; with `cond-let--', the package's prefix for private symbol. + +;; Users of this package are not expected to use these unwieldy +;; names. Instead one should use Emacs' shorthand feature to use +;; all or some of these macros by their conceptual names. E.g., if +;; you want to use all of the available macros, add this at the end +;; of a library. + +;; Local Variables: +;; read-symbol-shorthands: ( +;; ("and$" . "cond-let--and$") +;; ("and>" . "cond-let--and>") +;; ("and-let" . "cond-let--and-let") +;; ("if-let" . "cond-let--if-let") +;; ("when-let" . "cond-let--when-let") +;; ("while-let" . "cond-let--while-let")) +;; End: + +;; You can think of these file-local settings as import statements of +;; sorts. If you do this, then this package's implementations shadow +;; the built-in implementations. Doing so does not affect any other +;; libraries, which continue to use the built-in implementations. + +;; Due to limitations of the shorthand implementation this has to be +;; done for each individual library. "dir-locals.el" cannot be used. + +;; If you use `and$' and `and>', you might want to add this to your +;; configuration: + +;; (with-eval-after-load 'cond-let +;; (font-lock-add-keywords 'emacs-lisp-mode +;; cond-let-font-lock-keywords t)) + +;; For information about the individual macros, please refer to their +;; docstrings. + +;; See also https://github.com/tarsius/cond-let/wiki. + +;;; Code: +;;; Cond + +(defun cond-let--prepare-clauses (tag sequential clauses) + "Used by macros `cond-let*' and `cond-let'." + (let (body) + (dolist (clause (nreverse clauses)) + (cond + ((vectorp clause) + (setq body + `((,(if (and sequential (length> clause 1)) 'let* 'let) + ,(mapcar (lambda (vec) (append vec nil)) clause) + ,@body)))) + ((let (varlist) + (while (vectorp (car clause)) + (push (append (pop clause) nil) varlist)) + (push (cond + (varlist + `(,(pcase (list (and body t) + (and sequential (length> varlist 1))) + ('(t t ) 'cond-let--when-let*) + (`(t ,_) 'cond-let--when-let) + ('(nil t ) 'cond-let--and-let*) + (`(nil ,_) 'cond-let--and-let)) + ,(nreverse varlist) + ,(if body + `(throw ',tag ,(macroexp-progn clause)) + (macroexp-progn clause)))) + ((length= clause 1) + (if body + (let ((a (gensym "anon"))) + `(let ((,a ,(car clause))) + (when ,a (throw ',tag ,a)))) + (car clause))) + ((and (eq (car clause) t) (not body)) + (macroexp-progn (cdr clause))) + (t + `(when ,(pop clause) + (throw ',tag ,(macroexp-progn clause))))) + body))))) + body)) + +(defmacro cond-let* (&rest clauses) + "Try each clause until one succeeds. + +Each clause has one of these forms: +- a plain clause (CONDITION BODY...) +- a binding clause ([SYMBOL VALUEFORM]... BODY...) +- a binding vector [[SYMBOL VALUEFORM]...] + +A (CONDITION BODY...) clause works as for `cond'. Evaluate CONDITION, +and if it yields non-nil, the clause succeeds. Then evaluate BODY forms +sequentially and return the value of the last; or if there are no BODY +forms, return the value of CONDITION. If CONDITION yields nil, do not +evaluate the BODY forms and instead proceed to the next clause. + +A ([SYMBOL VALUEFORM]... BODY...) clause begins with one or more binding +vectors, followed by one or more BODY forms. Bind SYMBOL to the value +of VALUEFORM. Each VALUEFORM can refer to symbols already bound by this +VARLIST (as for `let*'). + +If all VALUEFORMs yield non-nil, evaluate BODY forms sequentially, with +VARLIST's bindings in effect, and return the value of the last form. + +If any VALUEFORM yields nil, evaluate neither the remaining VALUEFORMs +nor the BODY forms, and proceed to the next clause. + +A [[SYMBOL VALUEFORM]...] form creates bindings, which extend to all +remaining clauses and binding vectors. Unlike for the previous form, +always bind all SYMBOLs, even if a VALUEFORM yields nil. Always proceed +to the next clause." + (declare (indent 0) + (debug (&rest [&or + (vector &rest (vector symbolp form)) + ([&rest (vector symbolp form)] body) + (form body)]))) + (let ((tag (gensym ":cond-let*"))) + `(catch ',tag + ,@(cond-let--prepare-clauses tag t clauses)))) + +(defmacro cond-let (&rest clauses) + "Try each clause until one succeeds. + +Each clause has one of these forms: +- a plain clause (CONDITION BODY...) +- a binding clause ([SYMBOL VALUEFORM]... BODY...) +- a binding vector [[SYMBOL VALUEFORM]...] + +A (CONDITION BODY...) clause works as for `cond'. Evaluate CONDITION, +and if it yields non-nil, the clause succeeds. Then evaluate BODY forms +sequentially and return the value of the last; or if there are no BODY +forms, return the value of CONDITION. If CONDITION yields nil, do not +evaluate the BODY forms and instead proceed to the next clause. + +A ([SYMBOL VALUEFORM]... BODY...) clause begins with one or more binding +vectors, followed by one or more BODY forms. Bind SYMBOL to the value +of VALUEFORM. Evaluate all VALUEFORMs before binding their respective +SYMBOLs (as for `let'). + +If all VALUEFORMs yield non-nil, evaluate BODY forms sequentially, with +VARLIST's bindings in effect, and return the value of the last form. + +If any VALUEFORM yields nil, evaluate neither the remaining VALUEFORMs +nor the BODY forms, and proceed to the next clause. + +A [[SYMBOL VALUEFORM]...] form creates bindings, which extend to all +remaining clauses and binding vectors. Evaluate all VALUEFORMs before +binding their respective SYMBOLs. Unlike for the previous form, bind +all SYMBOLs, even if a VALUEFORM yields nil. Always proceed to the +next clause." + (declare (indent 0) (debug cond-let*)) + (let ((tag (gensym ":cond-let"))) + `(catch ',tag + ,@(cond-let--prepare-clauses tag nil clauses)))) + +;;; Common + +(defun cond-let--prepare-varlist (varlist) + "Used by Cond-Let's `when-let*', `and-let*' and `while-let*'. +Also used by other macros via `cond-let--prepare-varforms'. +Return (VARLIST LASTVAR)." + (let (prevvar) + (list (mapcar (lambda (binding) + (unless (length= binding 2) + (signal 'error (cons "Invalid binding" binding))) + (pcase-let ((`(,var ,form) binding)) + (when (string-prefix-p "_" (symbol-name var)) + (setq var (gensym "anon"))) + (prog1 (if prevvar + `(,var (and ,prevvar ,form)) + (list var form)) + (setq prevvar var)))) + varlist) + prevvar))) + +(defun cond-let--prepare-varforms (varlist &optional if-let) + "Used by Cond-Let's `when-let', `and-let', `while-let' and `if-let'. +Return (ANON-VARLIST ANON-SETQ VARLIST LASTVAR), or if the length of +VARLIST is 1 and IF-LET is nil, return (nil nil VARLIST LASTVAR)." + (if (and (not if-let) + (length= varlist 1)) + `(nil nil ,@(cond-let--prepare-varlist varlist)) + (let ((triples + (mapcar (lambda (binding) + (unless (length= binding 2) + (signal 'error (cons "Invalid binding" binding))) + (pcase-let ((`(,var ,form) binding)) + (when (string-prefix-p "_" (symbol-name var)) + (setq var nil)) + (list (and var (gensym "anon")) + var + form))) + varlist))) + (list (mapcan (pcase-lambda (`(,anon ,_ ,_)) + (and anon (list anon))) + triples) + (mapcar (pcase-lambda (`(,anon ,_ ,form)) + (if anon + `(setq ,anon ,form) + form)) + triples) + (mapcan (pcase-lambda (`(,anon ,var ,_)) + (and var `((,var ,anon)))) + triples) + (cadr (car (last triples))))))) + +;;; And + +(defmacro cond-let--and-let* (varlist &optional bodyform) + "Bind according to VARLIST until one yields nil, else evaluate BODYFORM. + +Each element of VARLIST is a list (SYMBOL VALUEFORM), which binds SYMBOL +to the value of VALUEFORM. Each VALUEFORM can refer to symbols already +bound by this VARLIST (as for `let*'). + +Evaluate VALUEFORMs until on of them yields nil. If that happens return +nil, and evaluate neither the remaining VALUEFORMs nor BODYFORM. If all +VALUEFORMs yield non-nil, evaluate BODYFORM with the bindings in effect, +and return its value; or if there is no BODYFORM, the value of the last +VALUEFORM." + (declare (indent 1) + (debug ((&rest (symbolp form)) form))) + (pcase-let ((`(,varlist ,lastvar) + (cond-let--prepare-varlist varlist))) + `(let* ,varlist + ,(if bodyform + `(and ,lastvar ,bodyform) + lastvar)))) + +(defmacro cond-let--and-let (varlist &optional bodyform) + "Bind according to VARLIST until one yields nil, else evaluate BODYFORM. + +Each element of VARLIST is a list (SYMBOL VALUEFORM), which binds SYMBOL +to the value of VALUEFORM. Evaluate all VALUEFORMs before binding their +respective SYMBOLs (as for `let'). + +Evaluate VALUEFORMs until on of them yields nil. If that happens return +nil, and evaluate neither the remaining VALUEFORMs nor BODYFORM. If all +VALUEFORMs yield non-nil, evaluate BODYFORM with the bindings in effect, +and return its value; or if there is no BODYFORM, the value of the last +VALUEFORM." + (declare (indent 1) (debug cond-let--and-let*)) + (pcase-let ((`(,anon ,set ,bind ,lastvar) + (cond-let--prepare-varforms varlist))) + (cond (anon + `(let ,anon + (and ,@set + (let ,bind + ,(or bodyform lastvar))))) + (t + `(let ,bind + ,(if bodyform + `(and ,lastvar ,bodyform) + lastvar)))))) + +(defmacro cond-let--and$ (varform bodyform) + "Bind variable `$' to value of VARFORM and conditionally evaluate BODYFORM. + +If VARFORM yields a non-nil value, bind the symbol `$' to that value, +evaluate BODYFORM with that binding in effect, and return the value of +BODYFORM. If VARFORM yields nil, do not evaluate BODYFORM, and return +nil." + (declare (debug (form form))) + `(let (($ ,varform)) + (and $ ,bodyform))) + +(defmacro cond-let--and> (form form2 &rest forms) + "Bind variables according to each VARFORM until one of them yields nil. + +Evaluate the first FORM and if that yields a non-nil value, bind the +symbol `$' to that value, and evaluate the next FORM with that binding +in effect. Repeat this process with subsequent FORMs until one yields +nil, then return nil without evaluate the remaining FORMs. If all +FORMs yield non-nil, return the value of the last FORM. + +\(fn FORM FORM...)" + (declare (debug (form form body))) + `(,(if forms 'let* 'let) + (($ ,form) + ,@(and forms + (mapcar (lambda (form) + `($ (and $ ,form))) + (cons form2 (butlast forms))))) + (and $ + ,(or (car (last forms)) + form2)))) + +;;; If + +(defmacro cond-let--if-let* (varlist then &rest else) + "Bind variables according to VARLIST and evaluate THEN or ELSE. + +Each element of VARLIST is a list (SYMBOL VALUEFORM), which binds SYMBOL +to the value of VALUEFORM. Each VALUEFORM can refer to symbols already +bound by this VARLIST (as for `let*'). + +If all VALUEFORMs yield non-nil, evaluate THEN with VARLIST's bindings +in effect, and return its value. THEN must be one expression. + +If any VALUEFORM yields nil, evaluate ELSE sequentially and return the +value of the last form; or if there are no ELSE forms return nil. The +bindings from VARLIST do _not_ extend to the ELSE forms. + +\(fn VARLIST THEN [ELSE...])" + (declare (indent 2) + (debug ((&rest (symbolp form)) form body))) + (pcase-let ((`(,varlist ,lastvar) + (cond-let--prepare-varlist varlist)) + (tag (gensym ":if-let*"))) + `(catch ',tag + (let* ,varlist + (when ,lastvar + (throw ',tag ,then))) + ,@else))) + +(defmacro cond-let--if-let (varlist then &rest else) + "Bind variables according to VARLIST and evaluate THEN or ELSE. + +Each element of VARLIST is a list (SYMBOL VALUEFORM), which binds SYMBOL +to the value of VALUEFORM. Evaluate all VALUEFORMs before binding their +respective SYMBOLs (as for `let'). + +If all VALUEFORMs yield non-nil, evaluate THEN with VARLIST's bindings +in effect, and return its value. THEN must be one expression. + +If any VALUEFORM yields nil, evaluate ELSE sequentially and return the +value of the last form; or if there are no ELSE forms return nil. The +bindings from VARLIST do _not_ extend to the ELSE forms. + +\(fn VARLIST THEN [ELSE...])" + (declare (indent 2) (debug cond-let--if-let*)) + (pcase-let* ((`(,anon ,set ,bind ,_) + (cond-let--prepare-varforms varlist t)) + (set (if (length= set 1) (car set) (cons 'and set)))) + `(let ,anon + (if ,set + (let ,bind + ,then) + ,@else)))) + +;;; When + +(defmacro cond-let--when-let* (varlist bodyform &rest body) + "Bind variables according to VARLIST and conditionally evaluate BODY. + +Each element of VARLIST is a list (SYMBOL VALUEFORM), which binds SYMBOL +to the value of VALUEFORM. Each VALUEFORM can refer to symbols already +bound by this VARLIST (as for `let*'). + +If all VALUEFORMs yield non-nil, evaluate BODY forms sequentially, with +VARLIST's bindings in effect, and return the value of the last form. + +If any VALUEFORM yields nil, evaluate neither the remaining VALUEFORMs +nor the BODY forms, and instead return nil. + +BODY must be one or more expressions. If VARLIST is empty, do nothing +and return nil. + +\(fn VARLIST BODY...)" + (declare (indent 1) + (debug ((&rest (symbolp form)) form body))) + (pcase-let ((`(,varlist ,lastvar) + (cond-let--prepare-varlist varlist))) + `(let* ,varlist + (when ,lastvar + ,bodyform ,@body)))) + +(defmacro cond-let--when-let (varlist bodyform &rest body) + "Bind variables according to VARLIST and conditionally evaluate BODY. + +Each element of VARLIST is a list (SYMBOL VALUEFORM), which binds SYMBOL +to the value of VALUEFORM. Evaluate all VALUEFORMs before binding their +respective SYMBOLs (as for `let'). + +If all VALUEFORMs yield non-nil, evaluate BODY forms sequentially, with +VARLIST's bindings in effect, and return the value of the last form. + +If any VALUEFORM yields nil, evaluate neither the remaining VALUEFORMs +nor the BODY forms, and instead return nil. + +BODY must be one or more expressions. If VARLIST is empty, do nothing +and return nil. + +\(fn VARLIST BODY...)" + (declare (indent 1) (debug cond-let--when-let*)) + (pcase-let ((`(,anon ,set ,bind ,lastvar) + (cond-let--prepare-varforms varlist))) + (cond (anon + `(let ,anon + (when (and ,@set) + (let ,bind + ,bodyform ,@body)))) + (t + `(let ,bind + (when ,lastvar + ,bodyform ,@body)))))) + +(defmacro cond-let--when$ (varform bodyform &rest body) + "Bind variable `$' to value of VARFORM and conditionally evaluate BODY. + +If VARFORM yields a non-nil value, bind the symbol `$' to that value, +evaluate BODY with that binding in effect, and return the value of the +last form. If VARFORM yields nil, do not evaluate BODY, and return nil. +BODY must be one or more expressions. If VARLIST is empty, do nothing +and return nil. + +\(fn VARLIST BODY...)" + (declare (debug (form form))) + `(let (($ ,varform)) + (when $ + ,bodyform ,@body))) + +;;; While + +(defmacro cond-let--while-let* (varlist &rest body) + "Bind variables according to VARLIST, conditionally evaluate BODY, and repeat. + +Each element of VARLIST is a list (SYMBOL VALUEFORM), which binds SYMBOL +to the value of VALUEFORM. Each VALUEFORM can refer to symbols already +bound by this VARLIST (as for `let*'). + +If all VALUEFORMs yield non-nil, evaluate BODY forms sequentially, with +VARLIST's bindings in effect, and repeat the loop. + +If any VALUEFORM yields nil, evaluate neither the remaining VALUEFORMs +nor the BODY forms, and instead return, always yielding nil. + +BODY can be zero or more expressions. + +\(fn VARLIST [BODY...])" + (declare (indent 1) (debug cond-let--if-let*)) + (pcase-let ((`(,varlist ,lastvar) + (cond-let--prepare-varlist varlist)) + (tag (gensym ":while-let*"))) + `(catch ',tag + (while t + (let* ,varlist + (if ,lastvar + ,(macroexp-progn body) + (throw ',tag nil))))))) + +(defmacro cond-let--while-let (varlist bodyform &rest body) + "Bind variables according to VARLIST, conditionally evaluate BODY, and repeat. + +Each element of VARLIST is a list (SYMBOL VALUEFORM), which binds SYMBOL +to the value of VALUEFORM. Evaluate all VALUEFORMs before binding their +respective SYMBOLs (as for `let'). + +If all VALUEFORMs yield non-nil, evaluate BODY forms sequentially, with +VARLIST's bindings in effect, and repeat the loop. + +If any VALUEFORM yields nil, evaluate neither the remaining VALUEFORMs +nor the BODY forms, and instead return, always yielding nil. + +BODY can be one or more expressions. + +\(fn VARLIST BODY...)" + (declare (indent 1) (debug cond-let--if-let*)) + (pcase-let ((`(,anon ,set ,bind ,lastvar) + (cond-let--prepare-varforms varlist)) + (tag (gensym ":while-let"))) + (cond (anon + `(catch ',tag + (while t + (let ,anon + (if (and ,@set) + (let ,bind + ,bodyform ,@body) + (throw ',tag nil)))))) + (t + `(catch ',tag + (while t + (let ,bind + (if ,lastvar + ,(macroexp-progn (cons bodyform body)) + (throw ',tag nil))))))))) + +;;; Font-Lock + +(defvar cond-let-font-lock-keywords + '(("\\_<\\$\\_>" 0 'font-lock-variable-name-face)) + "Highlight `$' using `font-lock-variable-name-face'. +To add these keywords, add this to your configuration: +\(font-lock-add-keywords \\='emacs-lisp-mode cond-let-font-lock-keywords t)") + +(provide 'cond-let) +;;; cond-let.el ends here diff --git a/lisp/nerd-icons/nerd-icons-pkg.el b/lisp/nerd-icons/nerd-icons-pkg.el index 7e50bbeb..ad31b1c6 100644 --- a/lisp/nerd-icons/nerd-icons-pkg.el +++ b/lisp/nerd-icons/nerd-icons-pkg.el @@ -1,10 +1,10 @@ ;; -*- no-byte-compile: t; lexical-binding: nil -*- -(define-package "nerd-icons" "20251108.1545" +(define-package "nerd-icons" "20251125.1823" "Emacs Nerd Font Icons Library." '((emacs "25.1")) :url "https://github.com/rainstormstudio/nerd-icons.el" - :commit "940b28d3dbd134696ef448e906e42a87a9d61e20" - :revdesc "940b28d3dbd1" + :commit "772987a28d6408f840331c52c91d04b623a87048" + :revdesc "772987a28d64" :keywords '("lisp") :authors '(("Hongyu Ding" . "rainstormstudio@yahoo.com") ("Vincent Zhang" . "seagle0128@gmail.com")) diff --git a/lisp/nerd-icons/nerd-icons.el b/lisp/nerd-icons/nerd-icons.el index 8d5723cd..20f11f02 100644 --- a/lisp/nerd-icons/nerd-icons.el +++ b/lisp/nerd-icons/nerd-icons.el @@ -4,8 +4,8 @@ ;; Author: Hongyu Ding , Vincent Zhang ;; Keywords: lisp -;; Package-Version: 20251108.1545 -;; Package-Revision: 940b28d3dbd1 +;; Package-Version: 20251125.1823 +;; Package-Revision: 772987a28d64 ;; Package-Requires: ((emacs "25.1")) ;; URL: https://github.com/rainstormstudio/nerd-icons.el ;; Keywords: convenient, lisp @@ -1069,18 +1069,17 @@ (defun nerd-icons-auto-mode-match? (&optional file) "Whether or not FILE's `major-mode' match against its `auto-mode-alist'." (let* ((file (or file (buffer-file-name) (buffer-name))) - (auto-mode (nerd-icons-match-to-alist file auto-mode-alist))) + (auto-mode (nerd-icons--auto-mode-lookup (file-name-nondirectory file)))) (eq major-mode auto-mode))) -(defvar nerd-icons--file-cache (make-hash-table :test 'equal) - "Cache for file extension to mode mapping.") +(defun nerd-icons--auto-mode-lookup (file) + "Return the mode-setting function associated with FILE via `auto-mode-alist'. +NOTE: The mode-setting function may not be the same as the mode itself." + (nerd-icons-match-to-alist file auto-mode-alist)) -(defun nerd-icons-match-to-alist (file alist) - "Match FILE against an entry in ALIST using `string-match'." - (or (gethash file nerd-icons--file-cache) - (puthash file - (cdr (cl-find-if (lambda (it) (string-match (car it) file)) alist)) - nerd-icons--file-cache))) +(defun nerd-icons-match-to-alist (string alist) + "Match STRING against an entry in ALIST using `string-match'." + (cdr (assoc string alist #'string-match))) (defun nerd-icons-dir-is-submodule (dir) "Checker whether or not DIR is a git submodule." @@ -1285,23 +1284,25 @@ icon." (unless (get func 'nerd-icons--cached) (let ((cache (make-hash-table :test #'equal :size nerd-icons--cache-limit)) - (orig-fn (symbol-function func))) + (orig-fn (symbol-function func)) + (unset (make-symbol "unset"))) (fset func (lambda (&rest args) - (or (gethash args cache) - (progn - (when (> (hash-table-count cache) - nerd-icons--cache-limit) - (clrhash cache)) - (puthash args (apply orig-fn args) cache))))))) - - (put func 'nerd-icons--cached t)) + (let ((value (gethash args cache unset))) + (when (eq value unset) + (when (> (hash-table-count cache) + nerd-icons--cache-limit) + (clrhash cache)) + (setq value (puthash args (apply orig-fn args) cache))) + value)))) + (put func 'nerd-icons--cached t))) (nerd-icons-cache #'nerd-icons-icon-for-dir) (nerd-icons-cache #'nerd-icons-icon-for-file) (nerd-icons-cache #'nerd-icons-icon-for-extension) (nerd-icons-cache #'nerd-icons-icon-for-mode) (nerd-icons-cache #'nerd-icons-icon-for-url) +(nerd-icons-cache #'nerd-icons--auto-mode-lookup) ;; Weather icons (defun nerd-icons-icon-for-weather (weather) @@ -1310,6 +1311,8 @@ icon." (when icon (apply (car icon) (cdr icon))))) +(nerd-icons-cache #'nerd-icons-icon-for-weather) + (eval-and-compile (defun nerd-icons--function-name (name) "Get the symbol for an icon function name for icon set NAME."