update packages, fix
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
8
lisp/cond-let/cond-let-pkg.el
Normal file
8
lisp/cond-let/cond-let-pkg.el
Normal file
@@ -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"))
|
||||
534
lisp/cond-let/cond-let.el
Normal file
534
lisp/cond-let/cond-let.el
Normal file
@@ -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 <emacs.cond-let@jonas.bernoulli.dev>
|
||||
;; 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; 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
|
||||
@@ -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"))
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
|
||||
;; Author: Hongyu Ding <rainstormstudio@yahoo.com>, Vincent Zhang <seagle0128@gmail.com>
|
||||
;; 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."
|
||||
|
||||
Reference in New Issue
Block a user