* Byte-compilation of custom themes @ 2018-01-20 21:01 Basil L. Contovounesios 2018-01-24 16:16 ` Stefan Monnier 0 siblings, 1 reply; 33+ messages in thread From: Basil L. Contovounesios @ 2018-01-20 21:01 UTC (permalink / raw To: emacs-devel This email is a follow-up to a question[1] I asked on the Emacs Stack Exchange Q&A forum a couple of months ago, which received no answers in the interim. [1] https://emacs.stackexchange.com/q/36892/15748 I am wondering why custom themes are ordinarily left non-byte-compiled, based on the following observations: 1. All built-in themes under etc/themes/ set the file variable no-byte-compile to t. 2. The function custom-available-themes in lisp/custom.el considers only *-theme.el and not *-theme.elc files under custom-theme-load-path. 3. The command load-theme in lisp/custom.el is able to load *-theme.elc files under custom-theme-load-path, but does so only if there is no corresponding source file in the same directory. 4. The manual nodes '(elisp) Custom Themes', '(emacs) Custom Themes' and '(emacs) Creating Custom Themes' make no mention of byte-compilation. Is this "aversion" to byte-compilation of custom themes intentional? If so, what is the reasoning behind it? Should the documentation be extended to describe it? If not, should the functions custom-available-themes and load-theme be made made less picky about which file extensions they consider? Should the behaviour of the latter be likened more to the that of the load function in src/lread.c? FWIW, I have not noticed any issues when using my own byte-compiled custom themes. The only minor nuisance is having to keep the source files separate from their translations and out of custom-theme-load-path. Thanks, -- Basil ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Byte-compilation of custom themes 2018-01-20 21:01 Byte-compilation of custom themes Basil L. Contovounesios @ 2018-01-24 16:16 ` Stefan Monnier 2018-01-30 22:16 ` Basil L. Contovounesios 0 siblings, 1 reply; 33+ messages in thread From: Stefan Monnier @ 2018-01-24 16:16 UTC (permalink / raw To: emacs-devel > I am wondering why custom themes are ordinarily left non-byte-compiled, > based on the following observations: Good question. > Is this "aversion" to byte-compilation of custom themes intentional? I think it's due to the idea that users might download theme files from random places without realizing that it contains arbitrary Lisp code (contrary to normal Emacs packages where we consider that users should know that it contains arbitrary Lisp code). So we prompt users to confirm that they think the theme file is safe, and users can't be expected to assess the safety of a .elc file, so we insist on using the .el file, which the user can inspect without nearly as much pain. Stefan ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Byte-compilation of custom themes 2018-01-24 16:16 ` Stefan Monnier @ 2018-01-30 22:16 ` Basil L. Contovounesios 2018-01-31 2:26 ` Stefan Monnier 0 siblings, 1 reply; 33+ messages in thread From: Basil L. Contovounesios @ 2018-01-30 22:16 UTC (permalink / raw To: Stefan Monnier; +Cc: emacs-devel [-- Attachment #1: Type: text/plain, Size: 764 bytes --] Stefan Monnier <monnier@iro.umontreal.ca> writes: >> Is this "aversion" to byte-compilation of custom themes intentional? > > I think it's due to the idea that users might download theme files from > random places without realizing that it contains arbitrary Lisp code > (contrary to normal Emacs packages where we consider that users should > know that it contains arbitrary Lisp code). So we prompt users to > confirm that they think the theme file is safe, and users can't be > expected to assess the safety of a .elc file, so we insist on using the > .el file, which the user can inspect without nearly as much pain. Ah, that makes sense. Do you think it would be worthwhile clarifying this in the manual? Is there a clearer way of saying the following? [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: foo.diff --] [-- Type: text/x-diff, Size: 754 bytes --] diff --git a/doc/lispref/customize.texi b/doc/lispref/customize.texi index 6c7ca260ab..7fea507fd0 100644 --- a/doc/lispref/customize.texi +++ b/doc/lispref/customize.texi @@ -1432,7 +1432,9 @@ Custom Themes would be evaluated when loading the theme, but that is bad form. To protect against loading themes containing malicious code, Emacs displays the source file and asks for confirmation from the user -before loading any non-built-in theme for the first time. +before loading any non-built-in theme for the first time. As +such, themes are not ordinarily byte-compiled, and source files +always take precedence when Emacs is looking for a theme to load. The following functions are useful for programmatically enabling and disabling themes: [-- Attachment #3: Type: text/plain, Size: 254 bytes --] Why are built-in themes not exempt to this safety net, though? Diminishing returns? Finally, would you care to post your helpful explanation as an answer to my Stack Exchange question, or would you rather I paraphrased this thread? Thanks, -- Basil ^ permalink raw reply related [flat|nested] 33+ messages in thread
* Re: Byte-compilation of custom themes 2018-01-30 22:16 ` Basil L. Contovounesios @ 2018-01-31 2:26 ` Stefan Monnier 2018-02-01 0:45 ` Basil L. Contovounesios 0 siblings, 1 reply; 33+ messages in thread From: Stefan Monnier @ 2018-01-31 2:26 UTC (permalink / raw To: Basil L. Contovounesios; +Cc: emacs-devel > diff --git a/doc/lispref/customize.texi b/doc/lispref/customize.texi > index 6c7ca260ab..7fea507fd0 100644 > --- a/doc/lispref/customize.texi > +++ b/doc/lispref/customize.texi > @@ -1432,7 +1432,9 @@ Custom Themes > would be evaluated when loading the theme, but that is bad form. > To protect against loading themes containing malicious code, Emacs > displays the source file and asks for confirmation from the user > -before loading any non-built-in theme for the first time. > +before loading any non-built-in theme for the first time. As > +such, themes are not ordinarily byte-compiled, and source files > +always take precedence when Emacs is looking for a theme to load. > > The following functions are useful for programmatically enabling and > disabling themes: Sounds good to me. > Why are built-in themes not exempt to this safety net, though? They're not? There is code which tries to exempt them, so if they're not, it's a bug in that code. > Finally, would you care to post your helpful explanation as an answer to > my Stack Exchange question, or would you rather I paraphrased this > thread? Feel free to post my answer there, Stefan ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Byte-compilation of custom themes 2018-01-31 2:26 ` Stefan Monnier @ 2018-02-01 0:45 ` Basil L. Contovounesios 2018-02-02 14:25 ` Stefan Monnier 0 siblings, 1 reply; 33+ messages in thread From: Basil L. Contovounesios @ 2018-02-01 0:45 UTC (permalink / raw To: Stefan Monnier; +Cc: emacs-devel [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: 0001-Clarify-byte-compilation-of-Custom-Themes-in-Elisp-m.patch --] [-- Type: text/x-diff, Size: 1270 bytes --] From 49288975a810d1f2186f656cede92db93ee85c56 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Wed, 31 Jan 2018 23:23:49 +0000 Subject: [PATCH] Clarify byte-compilation of "Custom Themes" in Elisp manual * doc/lispref/customize.texi (Custom Themes): Clarify status of byte-compiled custom themes. Suggested in https://lists.gnu.org/archive/html/emacs-devel/2018-01/msg00824.html. --- doc/lispref/customize.texi | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/lispref/customize.texi b/doc/lispref/customize.texi index 6c7ca260ab..7fea507fd0 100644 --- a/doc/lispref/customize.texi +++ b/doc/lispref/customize.texi @@ -1432,7 +1432,9 @@ Custom Themes would be evaluated when loading the theme, but that is bad form. To protect against loading themes containing malicious code, Emacs displays the source file and asks for confirmation from the user -before loading any non-built-in theme for the first time. +before loading any non-built-in theme for the first time. As +such, themes are not ordinarily byte-compiled, and source files +always take precedence when Emacs is looking for a theme to load. The following functions are useful for programmatically enabling and disabling themes: -- 2.15.1 [-- Attachment #2: Type: text/plain, Size: 1747 bytes --] Stefan Monnier <monnier@IRO.UMontreal.CA> writes: >> diff --git a/doc/lispref/customize.texi b/doc/lispref/customize.texi >> index 6c7ca260ab..7fea507fd0 100644 >> --- a/doc/lispref/customize.texi >> +++ b/doc/lispref/customize.texi >> @@ -1432,7 +1432,9 @@ Custom Themes >> would be evaluated when loading the theme, but that is bad form. >> To protect against loading themes containing malicious code, Emacs >> displays the source file and asks for confirmation from the user >> -before loading any non-built-in theme for the first time. >> +before loading any non-built-in theme for the first time. As >> +such, themes are not ordinarily byte-compiled, and source files >> +always take precedence when Emacs is looking for a theme to load. >> >> The following functions are useful for programmatically enabling and >> disabling themes: > > Sounds good to me. I attach a patch with this amendment. If it is up to scratch, would someone please push it? >> Why are built-in themes not exempt to this safety net, though? > > They're not? There is code which tries to exempt them, so if they're > not, it's a bug in that code. Sorry, I should have been clearer. As documented, load-theme indeed exempts built-in themes from the custom-theme-load-confirm check. What I meant to ask is why built-in themes are not byte-compiled in addition to being considered safe. Are there any arguments against doing this, other than any performance gain being negligible? >> Finally, would you care to post your helpful explanation as an answer to >> my Stack Exchange question, or would you rather I paraphrased this >> thread? > > Feel free to post my answer there, Done: https://emacs.stackexchange.com/a/38510/15748. Thanks, -- Basil ^ permalink raw reply related [flat|nested] 33+ messages in thread
* Re: Byte-compilation of custom themes 2018-02-01 0:45 ` Basil L. Contovounesios @ 2018-02-02 14:25 ` Stefan Monnier 2018-05-10 2:49 ` Basil L. Contovounesios 0 siblings, 1 reply; 33+ messages in thread From: Stefan Monnier @ 2018-02-02 14:25 UTC (permalink / raw To: Basil L. Contovounesios; +Cc: emacs-devel > I attach a patch with this amendment. Installed in the emacs-26 branch, thank you. > What I meant to ask is why built-in themes are not byte-compiled in > addition to being considered safe. Are there any arguments against > doing this, other than any performance gain being negligible? I can't think of any technical reason, indeed (except that we'd then have to special case this in the code so as to load the .elc file instead of the .el file). Stefan ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Byte-compilation of custom themes 2018-02-02 14:25 ` Stefan Monnier @ 2018-05-10 2:49 ` Basil L. Contovounesios 2018-05-10 2:54 ` Basil L. Contovounesios 2018-05-11 14:02 ` Eli Zaretskii 0 siblings, 2 replies; 33+ messages in thread From: Basil L. Contovounesios @ 2018-05-10 2:49 UTC (permalink / raw To: Stefan Monnier; +Cc: emacs-devel [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: 0001-Improve-loading-of-byte-compiled-custom-themes.patch --] [-- Type: text/x-diff, Size: 4290 bytes --] From bfab661fce5ab91a5f589172c4929371b776e59e Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Wed, 9 May 2018 22:20:47 +0100 Subject: [PATCH 1/8] Improve loading of byte-compiled custom themes * lisp/custom.el (load-theme): Load byte-compiled file of safe themes when available. https://lists.gnu.org/archive/html/emacs-devel/2018-01/msg00614.html https://lists.gnu.org/archive/html/emacs-devel/2018-02/msg00060.html --- lisp/custom.el | 78 ++++++++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 37 deletions(-) diff --git a/lisp/custom.el b/lisp/custom.el index b7539685a8..1fed5dce53 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -1221,43 +1221,47 @@ load-theme (put theme 'theme-settings nil) (put theme 'theme-feature nil) (put theme 'theme-documentation nil)) - (let ((fn (locate-file (concat (symbol-name theme) "-theme.el") - (custom-theme--load-path) - '("" "c")))) - (unless fn - (error "Unable to find theme file for `%s'" theme)) - (with-temp-buffer - (insert-file-contents fn) - ;; Check file safety with `custom-safe-themes', prompting the - ;; user if necessary. - (when (or no-confirm - (eq custom-safe-themes t) - (and (memq 'default custom-safe-themes) - (equal (file-name-directory fn) - (expand-file-name "themes/" data-directory))) - (let ((hash (secure-hash 'sha256 (current-buffer)))) - (or (member hash custom-safe-themes) - (custom-theme-load-confirm hash)))) - (let ((custom--inhibit-theme-enable t) - (buffer-file-name fn)) ;For load-history. - (eval-buffer)) - ;; Optimization: if the theme changes the `default' face, put that - ;; entry first. This avoids some `frame-set-background-mode' rigmarole - ;; by assigning the new background immediately. - (let* ((settings (get theme 'theme-settings)) - (tail settings) - found) - (while (and tail (not found)) - (and (eq (nth 0 (car tail)) 'theme-face) - (eq (nth 1 (car tail)) 'default) - (setq found (car tail))) - (setq tail (cdr tail))) - (if found - (put theme 'theme-settings (cons found (delq found settings))))) - ;; Finally, enable the theme. - (unless no-enable - (enable-theme theme)) - t)))) + (let ((file (locate-file (concat (symbol-name theme) "-theme.el") + (custom-theme--load-path) + '("" "c"))) + (custom--inhibit-theme-enable t)) + ;; Check file safety with `custom-safe-themes', prompting the + ;; user if necessary. + (cond ((not file) + (error "Unable to find theme file for `%s'" theme)) + ((or no-confirm + (eq custom-safe-themes t) + (and (memq 'default custom-safe-themes) + (equal (file-name-directory file) + (expand-file-name "themes/" data-directory)))) + ;; Theme is safe; load byte-compiled version if available. + (load (file-name-sans-extension file) nil t nil t)) + ((with-temp-buffer + (insert-file-contents file) + (let ((hash (secure-hash 'sha256 (current-buffer)))) + (when (or (member hash custom-safe-themes) + (custom-theme-load-confirm hash)) + (eval-buffer nil nil file) + t)))) + (t + (error "Unable to load theme `%s'" theme)))) + ;; Optimization: if the theme changes the `default' face, put that + ;; entry first. This avoids some `frame-set-background-mode' rigmarole + ;; by assigning the new background immediately. + (let* ((settings (get theme 'theme-settings)) + (tail settings) + found) + (while (and tail (not found)) + (and (eq (nth 0 (car tail)) 'theme-face) + (eq (nth 1 (car tail)) 'default) + (setq found (car tail))) + (setq tail (cdr tail))) + (when found + (put theme 'theme-settings (cons found (delq found settings))))) + ;; Finally, enable the theme. + (unless no-enable + (enable-theme theme)) + t) (defun custom-theme-load-confirm (hash) "Query the user about loading a Custom theme that may not be safe. -- 2.17.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: 0002-Disable-no-byte-compile-in-built-in-themes.patch --] [-- Type: text/x-diff, Size: 6291 bytes --] From 76939a778e7364750caa41e48695cfca4026f094 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Wed, 9 May 2018 22:30:48 +0100 Subject: [PATCH 2/8] Disable no-byte-compile in built-in themes * etc/themes/adwaita-theme.el: * etc/themes/deeper-blue-theme.el: * etc/themes/dichromacy-theme.el: * etc/themes/leuven-theme.el: * etc/themes/light-blue-theme.el: * etc/themes/manoj-dark-theme.el: * etc/themes/misterioso-theme.el: * etc/themes/tango-dark-theme.el: * etc/themes/tango-theme.el: * etc/themes/tsdh-dark-theme.el: * etc/themes/tsdh-light-theme.el: * etc/themes/wheatgrass-theme.el: * etc/themes/whiteboard-theme.el: * etc/themes/wombat-theme.el: Disable no-byte-compile. https://lists.gnu.org/archive/html/emacs-devel/2018-01/msg00614.html https://lists.gnu.org/archive/html/emacs-devel/2018-02/msg00060.html --- etc/themes/adwaita-theme.el | 4 ---- etc/themes/deeper-blue-theme.el | 4 ---- etc/themes/dichromacy-theme.el | 4 ---- etc/themes/leuven-theme.el | 1 - etc/themes/light-blue-theme.el | 4 ---- etc/themes/manoj-dark-theme.el | 4 ---- etc/themes/misterioso-theme.el | 4 ---- etc/themes/tango-dark-theme.el | 4 ---- etc/themes/tango-theme.el | 4 ---- etc/themes/tsdh-dark-theme.el | 4 ---- etc/themes/tsdh-light-theme.el | 5 ----- etc/themes/wheatgrass-theme.el | 4 ---- etc/themes/whiteboard-theme.el | 4 ---- etc/themes/wombat-theme.el | 4 ---- 14 files changed, 54 deletions(-) diff --git a/etc/themes/adwaita-theme.el b/etc/themes/adwaita-theme.el index b376153510..415db8a191 100644 --- a/etc/themes/adwaita-theme.el +++ b/etc/themes/adwaita-theme.el @@ -99,8 +99,4 @@ adwaita `(diff-added ((,class (:bold t :foreground "#4E9A06")))) `(diff-removed ((,class (:bold t :foreground "#F5666D")))))) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; adwaita-theme.el ends here diff --git a/etc/themes/deeper-blue-theme.el b/etc/themes/deeper-blue-theme.el index c6aa1751f4..0700f4f23d 100644 --- a/etc/themes/deeper-blue-theme.el +++ b/etc/themes/deeper-blue-theme.el @@ -110,8 +110,4 @@ deeper-blue (provide-theme 'deeper-blue) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; deeper-blue-theme.el ends here diff --git a/etc/themes/dichromacy-theme.el b/etc/themes/dichromacy-theme.el index 793209c055..bfced43aee 100644 --- a/etc/themes/dichromacy-theme.el +++ b/etc/themes/dichromacy-theme.el @@ -122,8 +122,4 @@ dichromacy (provide-theme 'dichromacy) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; dichromacy-theme.el ends here diff --git a/etc/themes/leuven-theme.el b/etc/themes/leuven-theme.el index 5c0d19ce81..c3c666588b 100644 --- a/etc/themes/leuven-theme.el +++ b/etc/themes/leuven-theme.el @@ -708,7 +708,6 @@ leuven ;; time-stamp-format: "%:y%02m%02d.%02H%02M" ;; time-stamp-start: "Version: " ;; time-stamp-end: "$" -;; no-byte-compile: t ;; End: ;;; leuven-theme.el ends here diff --git a/etc/themes/light-blue-theme.el b/etc/themes/light-blue-theme.el index 9935c565fb..ba00db6a49 100644 --- a/etc/themes/light-blue-theme.el +++ b/etc/themes/light-blue-theme.el @@ -61,8 +61,4 @@ light-blue (provide-theme 'light-blue) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; light-blue-theme.el ends here diff --git a/etc/themes/manoj-dark-theme.el b/etc/themes/manoj-dark-theme.el index fe61441d78..ddcaa0bd99 100644 --- a/etc/themes/manoj-dark-theme.el +++ b/etc/themes/manoj-dark-theme.el @@ -700,8 +700,4 @@ manoj-dark (provide-theme 'manoj-dark) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; manoj-dark.el ends here diff --git a/etc/themes/misterioso-theme.el b/etc/themes/misterioso-theme.el index 42e448d28b..6c1eec0f42 100644 --- a/etc/themes/misterioso-theme.el +++ b/etc/themes/misterioso-theme.el @@ -103,8 +103,4 @@ misterioso (provide-theme 'misterioso) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; misterioso-theme.el ends here diff --git a/etc/themes/tango-dark-theme.el b/etc/themes/tango-dark-theme.el index 3b6eeb702e..dae77a5e62 100644 --- a/etc/themes/tango-dark-theme.el +++ b/etc/themes/tango-dark-theme.el @@ -170,8 +170,4 @@ tango-dark (provide-theme 'tango-dark) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; tango-dark-theme.el ends here diff --git a/etc/themes/tango-theme.el b/etc/themes/tango-theme.el index a7a79c04ad..4fe2480bc7 100644 --- a/etc/themes/tango-theme.el +++ b/etc/themes/tango-theme.el @@ -154,8 +154,4 @@ tango (provide-theme 'tango) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; tango-theme.el ends here diff --git a/etc/themes/tsdh-dark-theme.el b/etc/themes/tsdh-dark-theme.el index 287fef8253..c216750cb2 100644 --- a/etc/themes/tsdh-dark-theme.el +++ b/etc/themes/tsdh-dark-theme.el @@ -144,8 +144,4 @@ tsdh-dark (provide-theme 'tsdh-dark) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; tsdh-dark-theme.el ends here diff --git a/etc/themes/tsdh-light-theme.el b/etc/themes/tsdh-light-theme.el index 17a86fdbfe..ce9d1a2c3c 100644 --- a/etc/themes/tsdh-light-theme.el +++ b/etc/themes/tsdh-light-theme.el @@ -106,9 +106,4 @@ tsdh-light (provide-theme 'tsdh-light) - -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; tsdh-light-theme.el ends here diff --git a/etc/themes/wheatgrass-theme.el b/etc/themes/wheatgrass-theme.el index 9585e3aa6e..8d34c28bf4 100644 --- a/etc/themes/wheatgrass-theme.el +++ b/etc/themes/wheatgrass-theme.el @@ -83,8 +83,4 @@ wheatgrass (provide-theme 'wheatgrass) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; wheatgrass-theme.el ends here diff --git a/etc/themes/whiteboard-theme.el b/etc/themes/whiteboard-theme.el index 5db0ddd68d..fe46cb0928 100644 --- a/etc/themes/whiteboard-theme.el +++ b/etc/themes/whiteboard-theme.el @@ -100,8 +100,4 @@ whiteboard (provide-theme 'whiteboard) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; whiteboard-theme.el ends here diff --git a/etc/themes/wombat-theme.el b/etc/themes/wombat-theme.el index 583b8dc3f6..00f29bb9fa 100644 --- a/etc/themes/wombat-theme.el +++ b/etc/themes/wombat-theme.el @@ -102,8 +102,4 @@ wombat (provide-theme 'wombat) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; wombat-theme.el ends here -- 2.17.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #3: 0003-Fix-custom-available-themes-file-expansion.patch --] [-- Type: text/x-diff, Size: 1625 bytes --] From abd12437c69afb72e206de2d0ea96d1326717909 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Wed, 2 May 2018 21:18:24 +0100 Subject: [PATCH 3/8] Fix custom-available-themes file expansion * lisp/custom.el: (custom-available-themes): Use directory-files instead of potentially mis-expanding filenames. --- lisp/custom.el | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/lisp/custom.el b/lisp/custom.el index 1fed5dce53..b286f49ff9 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -1299,17 +1299,15 @@ custom-available-themes loaded, and no effort is made to check that the files contain valid Custom themes. For a list of loaded themes, check the variable `custom-known-themes'." - (let (sym themes) + (let ((suffix "-theme\\.el\\'") + themes) (dolist (dir (custom-theme--load-path)) - (when (file-directory-p dir) - (dolist (file (file-expand-wildcards - (expand-file-name "*-theme.el" dir) t)) - (setq file (file-name-nondirectory file)) - (and (string-match "\\`\\(.+\\)-theme.el\\'" file) - (setq sym (intern (match-string 1 file))) - (custom-theme-name-valid-p sym) - (push sym themes))))) - (nreverse (delete-dups themes)))) + (dolist (file (directory-files dir nil suffix)) + (let ((theme (intern (substring file 0 (string-match-p suffix file))))) + (and (custom-theme-name-valid-p theme) + (not (memq theme themes)) + (push theme themes))))) + (nreverse themes))) (defun custom-theme--load-path () (let (lpath) -- 2.17.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #4: 0004-lisp-custom.el-Use-lexical-binding.patch --] [-- Type: text/x-diff, Size: 7586 bytes --] From 3233727e7ac7346bdcae28100805490365752b83 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Thu, 3 May 2018 15:47:02 +0100 Subject: [PATCH 4/8] * lisp/custom.el: Use lexical-binding (deftheme, custom-declare-theme): Fix advertised calling convention. (custom-enabled-themes): Fix message grammar. --- lisp/custom.el | 47 +++++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/lisp/custom.el b/lisp/custom.el index b286f49ff9..b8004cfd74 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -1,4 +1,4 @@ -;;; custom.el --- tools for declaring and initializing options +;;; custom.el --- tools for declaring and initializing options -*- lexical-binding: t -*- ;; ;; Copyright (C) 1996-1997, 1999, 2001-2018 Free Software Foundation, ;; Inc. @@ -150,7 +150,7 @@ custom-declare-variable (put symbol 'force-value nil)) (if (keywordp doc) (error "Doc string is missing")) - (let ((initialize 'custom-initialize-reset) + (let ((initialize #'custom-initialize-reset) (requests nil)) (unless (memq :group args) (custom-add-to-group (custom-current-group) symbol 'custom-variable)) @@ -426,7 +426,7 @@ custom-current-group (defun custom-declare-group (symbol members doc &rest args) "Like `defgroup', but SYMBOL is evaluated as a normal argument." (while members - (apply 'custom-add-to-group symbol (car members)) + (apply #'custom-add-to-group symbol (car members)) (setq members (cdr members))) (when doc ;; This text doesn't get into DOC. @@ -621,8 +621,8 @@ custom-note-var-changed \f ;;; Custom Themes -;;; Loading files needed to customize a symbol. -;;; This is in custom.el because menu-bar.el needs it for toggle cmds. +;; Loading files needed to customize a symbol. +;; This is in custom.el because menu-bar.el needs it for toggle cmds. (defvar custom-load-recursion nil "Hack to avoid recursive dependencies.") @@ -715,7 +715,7 @@ customize-mark-to-save Return non-nil if the `saved-value' property actually changed." (custom-load-symbol symbol) - (let* ((get (or (get symbol 'custom-get) 'default-value)) + (let* ((get (or (get symbol 'custom-get) #'default-value)) (value (funcall get symbol)) (saved (get symbol 'saved-value)) (standard (get symbol 'standard-value)) @@ -744,7 +744,7 @@ customize-mark-as-set Return non-nil if the `customized-value' property actually changed." (custom-load-symbol symbol) - (let* ((get (or (get symbol 'custom-get) 'default-value)) + (let* ((get (or (get symbol 'custom-get) #'default-value)) (value (funcall get symbol)) (customized (get symbol 'customized-value)) (old (or (get symbol 'saved-value) (get symbol 'standard-value)))) @@ -776,7 +776,7 @@ custom-reevaluate-setting ;; always do the funcall step, even if symbol was not bound before. (or (default-boundp symbol) (eval `(defvar ,symbol nil))) ; reset below, so any value is fine - (funcall (or (get symbol 'custom-set) 'set-default) + (funcall (or (get symbol 'custom-set) #'set-default) symbol (eval (car (or (get symbol 'saved-value) (get symbol 'standard-value)))))) @@ -941,7 +941,7 @@ custom-set-variables REQUEST is a list of features we must require in order to handle SYMBOL properly. COMMENT is a comment string about SYMBOL." - (apply 'custom-theme-set-variables 'user args)) + (apply #'custom-theme-set-variables 'user args)) (defun custom-theme-set-variables (theme &rest args) "Initialize variables for theme THEME according to settings in ARGS. @@ -989,8 +989,8 @@ custom-theme-set-variables set) (when requests (put symbol 'custom-requests requests) - (mapc 'require requests)) - (setq set (or (get symbol 'custom-set) 'custom-set-default)) + (mapc #'require requests)) + (setq set (or (get symbol 'custom-set) #'custom-set-default)) (put symbol 'saved-value (list value)) (put symbol 'saved-variable-comment comment) ;; Allow for errors in the case where the setter has @@ -1086,26 +1086,29 @@ custom--sort-vars-1 ;; they were used to supply keyword-value pairs like `:immediate', ;; `:variable-reset-string', etc. We don't use any of these, so ignore them. -(defmacro deftheme (theme &optional doc &rest ignored) +(defmacro deftheme (theme &optional doc &rest _ignored) "Declare THEME to be a Custom theme. The optional argument DOC is a doc string describing the theme. Any theme `foo' should be defined in a file called `foo-theme.el'; see `custom-make-theme-feature' for more information." - (declare (doc-string 2)) + (declare (doc-string 2) + (advertised-calling-convention (theme &optional doc) "22.1")) (let ((feature (custom-make-theme-feature theme))) ;; It is better not to use backquote in this file, ;; because that makes a bootstrapping problem ;; if you need to recompile all the Lisp files using interpreted code. (list 'custom-declare-theme (list 'quote theme) (list 'quote feature) doc))) -(defun custom-declare-theme (theme feature &optional doc &rest ignored) +(defun custom-declare-theme (theme feature &optional doc &rest _ignored) "Like `deftheme', but THEME is evaluated as a normal argument. FEATURE is the feature this theme provides. Normally, this is a symbol created from THEME by `custom-make-theme-feature'." + (declare (advertised-calling-convention (theme feature &optional doc) "22.1")) (unless (custom-theme-name-valid-p theme) (error "Custom theme cannot be named %S" theme)) - (add-to-list 'custom-known-themes theme) + (unless (memq theme custom-known-themes) + (push theme custom-known-themes)) (put theme 'theme-feature feature) (when doc (put theme 'theme-documentation doc))) @@ -1206,7 +1209,7 @@ load-theme (interactive (list (intern (completing-read "Load custom theme: " - (mapcar 'symbol-name + (mapcar #'symbol-name (custom-available-themes)))) nil nil)) (unless (custom-theme-name-valid-p theme) @@ -1387,9 +1390,9 @@ custom-enabled-themes themes (delq theme themes))))) (enable-theme 'user) (custom-set-default symbol themes) - (if failures - (message "Failed to enable theme: %s" - (mapconcat 'symbol-name failures ", ")))))) + (when failures + (message "Failed to enable theme(s): %s" + (mapconcat #'symbol-name failures ", ")))))) (defsubst custom-theme-enabled-p (theme) "Return non-nil if THEME is enabled." @@ -1401,7 +1404,7 @@ disable-theme (interactive (list (intern (completing-read "Disable custom theme: " - (mapcar 'symbol-name custom-enabled-themes) + (mapcar #'symbol-name custom-enabled-themes) nil t)))) (when (custom-theme-enabled-p theme) (let ((settings (get theme 'theme-settings))) @@ -1467,7 +1470,7 @@ custom-theme-recalc-variable (if (and valspec (or (get variable 'force-value) (default-boundp variable))) - (funcall (or (get variable 'custom-set) 'set-default) variable + (funcall (or (get variable 'custom-set) #'set-default) variable (eval (car valspec)))))) (defun custom-theme-recalc-face (face) @@ -1508,7 +1511,7 @@ custom-reset-variables (VARIABLE IGNORED) This means reset VARIABLE. (The argument IGNORED is ignored)." - (apply 'custom-theme-reset-variables 'user args)) + (apply #'custom-theme-reset-variables 'user args)) ;;; The End. -- 2.17.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #5: 0005-lisp-cus-theme.el-Use-lexical-binding.patch --] [-- Type: text/x-diff, Size: 7112 bytes --] From 9b7b979c430347466adc412050b5548c89d588c4 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Thu, 10 May 2018 02:31:17 +0100 Subject: [PATCH 5/8] * lisp/cus-theme.el: Use lexical-binding --- lisp/cus-theme.el | 50 +++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/lisp/cus-theme.el b/lisp/cus-theme.el index e5e787771b..760e531268 100644 --- a/lisp/cus-theme.el +++ b/lisp/cus-theme.el @@ -1,4 +1,4 @@ -;;; cus-theme.el -- custom theme creation user interface +;;; cus-theme.el -- custom theme creation user interface -*- lexical-binding: t -*- ;; ;; Copyright (C) 2001-2018 Free Software Foundation, Inc. ;; @@ -35,10 +35,10 @@ custom-new-theme-mode-map (set-keymap-parent map (make-composed-keymap widget-keymap special-mode-map)) (suppress-keymap map) - (define-key map "\C-x\C-s" 'custom-theme-write) - (define-key map "q" 'Custom-buffer-done) - (define-key map "n" 'widget-forward) - (define-key map "p" 'widget-backward) + (define-key map "\C-x\C-s" #'custom-theme-write) + (define-key map "q" #'Custom-buffer-done) + (define-key map "n" #'widget-forward) + (define-key map "p" #'widget-backward) map) "Keymap for `custom-new-theme-mode'.") @@ -47,7 +47,7 @@ custom-new-theme-mode Do not call this mode function yourself. It is meant for internal use." (use-local-map custom-new-theme-mode-map) (custom--initialize-widget-variables) - (set (make-local-variable 'revert-buffer-function) 'custom-theme-revert)) + (set (make-local-variable 'revert-buffer-function) #'custom-theme-revert)) (put 'custom-new-theme-mode 'mode-class 'special) (defvar custom-theme-name nil) @@ -118,13 +118,13 @@ customize-create-theme :tag " Visit Theme " :help-echo "Insert the settings of a pre-defined theme." :action (lambda (_widget &optional _event) - (call-interactively 'custom-theme-visit-theme))) + (call-interactively #'custom-theme-visit-theme))) (widget-insert " ") (widget-create 'push-button :tag " Merge Theme " :help-echo "Merge in the settings of a pre-defined theme." :action (lambda (_widget &optional _event) - (call-interactively 'custom-theme-merge-theme))) + (call-interactively #'custom-theme-merge-theme))) (widget-insert " ") (widget-create 'push-button :tag " Revert " @@ -142,7 +142,7 @@ customize-create-theme (widget-create 'text :value (format-time-string "Created %Y-%m-%d."))) (widget-create 'push-button - :notify (function custom-theme-write) + :notify #'custom-theme-write " Save Theme ") (when (eq theme 'user) (setq custom-theme--migrate-settings t) @@ -188,7 +188,7 @@ customize-create-theme :mouse-face 'highlight :pressed-face 'highlight :action (lambda (_widget &optional _event) - (call-interactively 'custom-theme-add-face))) + (call-interactively #'custom-theme-add-face))) ;; If THEME is non-nil, insert all of that theme's variables. (widget-insert "\n\n Theme variables:\n ") @@ -207,7 +207,7 @@ customize-create-theme :mouse-face 'highlight :pressed-face 'highlight :action (lambda (_widget &optional _event) - (call-interactively 'custom-theme-add-variable))) + (call-interactively #'custom-theme-add-variable))) (widget-insert ?\n) (widget-setup) (goto-char (point-min)) @@ -254,7 +254,7 @@ custom-theme-add-var-1 :tag (custom-unlispify-tag-name symbol) :value symbol :shown-value (list val) - :notify 'ignore + :notify #'ignore :custom-level 0 :custom-state 'hidden :custom-style 'simple)) @@ -313,7 +313,7 @@ custom-theme-visit-theme (interactive (list (intern (completing-read "Find custom theme: " - (mapcar 'symbol-name + (mapcar #'symbol-name (custom-available-themes)))))) (unless (custom-theme-name-valid-p theme) (error "No valid theme named `%s'" theme)) @@ -328,7 +328,7 @@ custom-theme-merge-theme (interactive (list (intern (completing-read "Merge custom theme: " - (mapcar 'symbol-name + (mapcar #'symbol-name (custom-available-themes)))))) (unless (eq theme 'user) (unless (custom-theme-name-valid-p theme) @@ -343,8 +343,8 @@ custom-theme-merge-theme (memq name '(custom-enabled-themes custom-safe-themes))) (funcall (if option - 'custom-theme-add-variable - 'custom-theme-add-face) + #'custom-theme-add-variable + #'custom-theme-add-face) name value))))) theme) @@ -475,7 +475,7 @@ describe-theme (interactive (list (intern (completing-read "Describe custom theme: " - (mapcar 'symbol-name + (mapcar #'symbol-name (custom-available-themes)))))) (unless (custom-theme-name-valid-p theme) (error "Invalid theme name `%s'" theme)) @@ -540,10 +540,10 @@ custom-theme-choose-mode-map (set-keymap-parent map (make-composed-keymap widget-keymap special-mode-map)) (suppress-keymap map) - (define-key map "\C-x\C-s" 'custom-theme-save) - (define-key map "n" 'widget-forward) - (define-key map "p" 'widget-backward) - (define-key map "?" 'custom-describe-theme) + (define-key map "\C-x\C-s" #'custom-theme-save) + (define-key map "n" #'widget-forward) + (define-key map "p" #'widget-backward) + (define-key map "?" #'custom-describe-theme) map) "Keymap for `custom-theme-choose-mode'.") @@ -616,11 +616,11 @@ customize-themes (widget-create 'push-button :tag " Save Theme Settings " :help-echo "Save the selected themes for future sessions." - :action 'custom-theme-save) + :action #'custom-theme-save) (widget-insert ?\n) (widget-create 'checkbox :value custom-theme-allow-multiple-selections - :action 'custom-theme-selections-toggle) + :action #'custom-theme-selections-toggle) (widget-insert (propertize " Select more than one theme at a time" 'face '(variable-pitch (:height 0.9)))) @@ -632,13 +632,13 @@ customize-themes :value (custom-theme-enabled-p theme) :theme-name theme :help-echo help-echo - :action 'custom-theme-checkbox-toggle)) + :action #'custom-theme-checkbox-toggle)) (push (cons theme widget) custom--listed-themes) (widget-create-child-and-convert widget 'push-button :button-face-get 'ignore :mouse-face-get 'ignore :value (format " %s" theme) - :action 'widget-parent-action + :action #'widget-parent-action :help-echo help-echo) (widget-insert " -- " (propertize (custom-theme-summary theme) -- 2.17.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #6: 0006-Various-custom.el-simplifications.patch --] [-- Type: text/x-diff, Size: 7949 bytes --] From 04c7fc5441ff1ad95eb03b9892675cae0f98fa72 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Thu, 3 May 2018 15:49:35 +0100 Subject: [PATCH 6/8] Various custom.el simplifications * lisp/custom.el (custom-load-symbol): Specify NOERROR argument when loading instead of wrapping in condition-case. (custom-quote): Duplicate macroexp-quote. (customize-mark-to-save, customize-mark-as-set, disable-theme) (custom-theme-name-valid-p, enable-theme, custom-enabled-themes): Simplify logic. --- lisp/custom.el | 102 ++++++++++++++++++++++--------------------------- 1 file changed, 45 insertions(+), 57 deletions(-) diff --git a/lisp/custom.el b/lisp/custom.el index b8004cfd74..ae917c0292 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -633,14 +633,10 @@ custom-load-symbol (let ((custom-load-recursion t)) ;; Load these files if not already done, ;; to make sure we know all the dependencies of SYMBOL. - (condition-case nil - (require 'cus-load) - (error nil)) - (condition-case nil - (require 'cus-start) - (error nil)) + (require 'cus-load nil t) + (require 'cus-start nil t) (dolist (load (get symbol 'custom-loads)) - (cond ((symbolp load) (condition-case nil (require load) (error nil))) + (cond ((symbolp load) (require load nil t)) ;; This is subsumed by the test below, but it's much faster. ((assoc load load-history)) ;; This was just (assoc (locate-library load) load-history) @@ -658,7 +654,7 @@ custom-load-symbol ;; We are still loading it when we call this, ;; and it is not in load-history yet. ((equal load "cus-edit")) - (t (condition-case nil (load load) (error nil)))))))) + (t (load load t))))))) \f (defvar custom-local-buffer nil "Non-nil, in a Customization buffer, means customize a specific buffer. @@ -691,16 +687,12 @@ custom-set-minor-mode (defun custom-quote (sexp) "Quote SEXP if it is not self quoting." - (if (or (memq sexp '(t nil)) - (keywordp sexp) - (and (listp sexp) - (memq (car sexp) '(lambda))) - (stringp sexp) - (numberp sexp) - (vectorp sexp) -;;; (and (fboundp 'characterp) -;;; (characterp sexp)) - ) + ;; Can't use `macroexp-quote' because it is loaded after `custom.el' + ;; during bootstrap. See `loadup.el'. + (if (and (not (consp sexp)) + (or (keywordp sexp) + (not (symbolp sexp)) + (booleanp sexp))) sexp (list 'quote sexp))) @@ -721,12 +713,11 @@ customize-mark-to-save (standard (get symbol 'standard-value)) (comment (get symbol 'customized-variable-comment))) ;; Save default value if different from standard value. - (if (or (null standard) - (not (equal value (condition-case nil - (eval (car standard)) - (error nil))))) - (put symbol 'saved-value (list (custom-quote value))) - (put symbol 'saved-value nil)) + (if (and standard + (equal value (ignore-errors + (eval (car standard))))) + (put symbol 'saved-value nil) + (put symbol 'saved-value (list (custom-quote value)))) ;; Clear customized information (set, but not saved). (put symbol 'customized-value nil) ;; Save any comment that might have been set. @@ -750,9 +741,8 @@ customize-mark-as-set (old (or (get symbol 'saved-value) (get symbol 'standard-value)))) ;; Mark default value as set if different from old value. (if (not (and old - (equal value (condition-case nil - (eval (car old)) - (error nil))))) + (equal value (ignore-errors + (eval (car old)))))) (progn (put symbol 'customized-value (list (custom-quote value))) (custom-push-theme 'theme-value symbol 'user 'set (custom-quote value))) @@ -1287,11 +1277,9 @@ custom-theme-load-confirm (defun custom-theme-name-valid-p (name) "Return t if NAME is a valid name for a Custom theme, nil otherwise. NAME should be a symbol." - (and (symbolp name) - name - (not (or (zerop (length (symbol-name name))) - (eq name 'user) - (eq name 'changed))))) + (and (not (memq name '(nil user changed))) + (symbolp name) + (not (string= "" (symbol-name name))))) (defun custom-available-themes () "Return a list of Custom themes available for loading. @@ -1335,8 +1323,8 @@ enable-theme (completing-read "Enable custom theme: " obarray (lambda (sym) (get sym 'theme-settings)) t)))) - (if (not (custom-theme-p theme)) - (error "Undefined Custom theme %s" theme)) + (unless (custom-theme-p theme) + (error "Undefined Custom theme %s" theme)) (let ((settings (get theme 'theme-settings))) ;; Loop through theme settings, recalculating vars/faces. (dolist (s settings) @@ -1376,18 +1364,18 @@ custom-enabled-themes (let (failures) (setq themes (delq 'user (delete-dups themes))) ;; Disable all themes not in THEMES. - (if (boundp symbol) - (dolist (theme (symbol-value symbol)) - (if (not (memq theme themes)) - (disable-theme theme)))) + (dolist (theme (and (boundp symbol) + (symbol-value symbol))) + (unless (memq theme themes) + (disable-theme theme))) ;; Call `enable-theme' or `load-theme' on each of THEMES. (dolist (theme (reverse themes)) (condition-case nil (if (custom-theme-p theme) (enable-theme theme) (load-theme theme)) - (error (setq failures (cons theme failures) - themes (delq theme themes))))) + (error (push theme failures) + (setq themes (delq theme themes))))) (enable-theme 'user) (custom-set-default symbol themes) (when failures @@ -1420,23 +1408,23 @@ disable-theme ;; If the face spec specified by this theme is in the ;; saved-face property, reset that property. (when (equal (nth 3 s) (get symbol 'saved-face)) - (put symbol 'saved-face (and val (cadr (car val))))))))) - ;; Recompute faces on all frames. - (dolist (frame (frame-list)) - ;; We must reset the fg and bg color frame parameters, or - ;; `face-set-after-frame-default' will use the existing - ;; parameters, which could be from the disabled theme. - (set-frame-parameter frame 'background-color - (custom--frame-color-default - frame :background "background" "Background" - "unspecified-bg" "white")) - (set-frame-parameter frame 'foreground-color - (custom--frame-color-default - frame :foreground "foreground" "Foreground" - "unspecified-fg" "black")) - (face-set-after-frame-default frame)) - (setq custom-enabled-themes - (delq theme custom-enabled-themes))))) + (put symbol 'saved-face (cadar val)))))))) + ;; Recompute faces on all frames. + (dolist (frame (frame-list)) + ;; We must reset the fg and bg color frame parameters, or + ;; `face-set-after-frame-default' will use the existing + ;; parameters, which could be from the disabled theme. + (set-frame-parameter frame 'background-color + (custom--frame-color-default + frame :background "background" "Background" + "unspecified-bg" "white")) + (set-frame-parameter frame 'foreground-color + (custom--frame-color-default + frame :foreground "foreground" "Foreground" + "unspecified-fg" "black")) + (face-set-after-frame-default frame)) + (setq custom-enabled-themes + (delq theme custom-enabled-themes)))) ;; Only used if window-system not null. (declare-function x-get-resource "frame.c" -- 2.17.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #7: 0007-Various-cus-theme.el-simplifications.patch --] [-- Type: text/x-diff, Size: 3934 bytes --] From c468916fa18a5ada2f5ff7413f998747bc0b9dec Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Thu, 10 May 2018 03:08:10 +0100 Subject: [PATCH 7/8] Various cus-theme.el simplifications * lisp/cus-theme.el (custom-new-theme-mode, customize-themes) (custom-theme-choose-mode): Use setq-local. (customize-create-theme): Ditto. Use delete-all-overlays. (describe-theme-1, custom-theme-summary): Simplify logic. --- lisp/cus-theme.el | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/lisp/cus-theme.el b/lisp/cus-theme.el index 760e531268..dbb9d1af90 100644 --- a/lisp/cus-theme.el +++ b/lisp/cus-theme.el @@ -47,7 +47,7 @@ custom-new-theme-mode Do not call this mode function yourself. It is meant for internal use." (use-local-map custom-new-theme-mode-map) (custom--initialize-widget-variables) - (set (make-local-variable 'revert-buffer-function) #'custom-theme-revert)) + (setq-local revert-buffer-function #'custom-theme-revert)) (put 'custom-new-theme-mode 'mode-class 'special) (defvar custom-theme-name nil) @@ -93,15 +93,14 @@ customize-create-theme (switch-to-buffer (get-buffer-create (or buffer "*Custom Theme*"))) (let ((inhibit-read-only t)) (erase-buffer) - (dolist (ov (overlays-in (point-min) (point-max))) - (delete-overlay ov))) + (delete-all-overlays)) (custom-new-theme-mode) (make-local-variable 'custom-theme-name) - (set (make-local-variable 'custom-theme--save-name) theme) - (set (make-local-variable 'custom-theme-faces) nil) - (set (make-local-variable 'custom-theme-variables) nil) - (set (make-local-variable 'custom-theme-description) "") - (set (make-local-variable 'custom-theme--migrate-settings) nil) + (setq-local custom-theme--save-name theme) + (setq-local custom-theme-faces nil) + (setq-local custom-theme-variables nil) + (setq-local custom-theme-description "") + (setq-local custom-theme--migrate-settings nil) (make-local-variable 'custom-theme-insert-face-marker) (make-local-variable 'custom-theme-insert-variable-marker) (make-local-variable 'custom-theme--listed-faces) @@ -513,8 +512,7 @@ describe-theme-1 (condition-case nil (read (current-buffer)) (end-of-file nil))))) - (and sexp (listp sexp) - (eq (car sexp) 'deftheme) + (and (eq (car-safe sexp) 'deftheme) (setq doc (nth 2 sexp))))))) (princ "\n\nDocumentation:\n") (princ (if (stringp doc) @@ -552,10 +550,10 @@ custom-theme-choose-mode Do not call this mode function yourself. It is meant for internal use." (use-local-map custom-theme-choose-mode-map) (custom--initialize-widget-variables) - (set (make-local-variable 'revert-buffer-function) - (lambda (_ignore-auto noconfirm) - (when (or noconfirm (y-or-n-p "Discard current choices? ")) - (customize-themes (current-buffer)))))) + (setq-local revert-buffer-function + (lambda (_ignore-auto noconfirm) + (when (or noconfirm (y-or-n-p "Discard current choices? ")) + (customize-themes (current-buffer)))))) (put 'custom-theme-choose-mode 'mode-class 'special) ;;;###autoload @@ -568,7 +566,7 @@ customize-themes (let ((inhibit-read-only t)) (erase-buffer)) (custom-theme-choose-mode) - (set (make-local-variable 'custom--listed-themes) nil) + (setq-local custom--listed-themes nil) (make-local-variable 'custom-theme-allow-multiple-selections) (and (null custom-theme-allow-multiple-selections) (> (length custom-enabled-themes) 1) @@ -662,8 +660,7 @@ custom-theme-summary (condition-case nil (read (current-buffer)) (end-of-file nil))))) - (and sexp (listp sexp) - (eq (car sexp) 'deftheme) + (and (eq (car-safe sexp) 'deftheme) (setq doc (nth 2 sexp)))))))) (cond ((null doc) "(no documentation available)") -- 2.17.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #8: 0008-Minor-subr-x-tweaks.patch --] [-- Type: text/x-diff, Size: 1193 bytes --] From 3921f5f18b4dcbcccb4761fac1edd539ac6ecdb3 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Thu, 3 May 2018 16:12:56 +0100 Subject: [PATCH 8/8] Minor subr-x tweaks * lisp/emacs-lisp/subr-x.el (string-join): #'-quote function symbol. (string-remove-suffix): One less call to length. --- lisp/emacs-lisp/subr-x.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el index 7fab9083e8..2ae31f593c 100644 --- a/lisp/emacs-lisp/subr-x.el +++ b/lisp/emacs-lisp/subr-x.el @@ -211,7 +211,7 @@ string-empty-p (defsubst string-join (strings &optional separator) "Join all STRINGS using SEPARATOR." - (mapconcat 'identity strings separator)) + (mapconcat #'identity strings separator)) (define-obsolete-function-alias 'string-reverse 'reverse "25.1") @@ -250,7 +250,7 @@ string-remove-prefix (defsubst string-remove-suffix (suffix string) "Remove SUFFIX from STRING if present." (if (string-suffix-p suffix string) - (substring string 0 (- (length string) (length suffix))) + (substring string 0 (- (length suffix))) string)) (provide 'subr-x) -- 2.17.0 [-- Attachment #9: Type: text/plain, Size: 1683 bytes --] Stefan Monnier <monnier@IRO.UMontreal.CA> writes: >> What I meant to ask is why built-in themes are not byte-compiled in >> addition to being considered safe. Are there any arguments against >> doing this, other than any performance gain being negligible? > > I can't think of any technical reason, indeed (except that we'd then > have to special case this in the code so as to load the .elc file > instead of the .el file). I went ahead and modified load-theme to support loading byte-compiled themes considered safe, but then I couldn't resist tweaking some of the surrounding (in that it all lives under the lisp/ directory) code, so I attach 8 patches. The first makes load-theme call load instead of insert-file-contents+eval-buffer in the non-interactive case of the theme being considered safe. This allows either .elc or .el themes to be loaded with the same semantics as usual Elisp loading. The second disables the file-local variable no-byte-compile in all the built-in themes. Would we want to go one step further and include theme byte-compilation as part of the build? Or does that entail too much effort for little to no gain? The third simplifies the function custom-available-themes and also fixes a theoretical issue with its arbitrary expansion of wildcards in custom theme filenames. The fourth and fifth enable lexical-binding in custom.el and cus-theme.el, respectively. The last three try to make various logic simplifications in custom.el, cus-theme.el, and subr-x.el, respectively. I hope this isn't dumping too much in one go. Please let me know how I can improve these patches, should any of their suggestions be welcome. Thanks, -- Basil ^ permalink raw reply related [flat|nested] 33+ messages in thread
* Re: Byte-compilation of custom themes 2018-05-10 2:49 ` Basil L. Contovounesios @ 2018-05-10 2:54 ` Basil L. Contovounesios 2018-05-11 14:07 ` Eli Zaretskii 2018-05-11 14:02 ` Eli Zaretskii 1 sibling, 1 reply; 33+ messages in thread From: Basil L. Contovounesios @ 2018-05-10 2:54 UTC (permalink / raw To: Stefan Monnier; +Cc: emacs-devel "Basil L. Contovounesios" <contovob@tcd.ie> writes: > I went ahead and modified load-theme to support loading byte-compiled > themes considered safe, but then I couldn't resist tweaking some of the > surrounding (in that it all lives under the lisp/ directory) code, so I > attach 8 patches. I forgot to ask in my previous email whether the duplicate ';;; Custom Themes' headings in custom.el are intentional, and if not how they might be better shuffled around. -- Basil ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Byte-compilation of custom themes 2018-05-10 2:54 ` Basil L. Contovounesios @ 2018-05-11 14:07 ` Eli Zaretskii 0 siblings, 0 replies; 33+ messages in thread From: Eli Zaretskii @ 2018-05-11 14:07 UTC (permalink / raw To: Basil L. Contovounesios; +Cc: monnier, emacs-devel > From: "Basil L. Contovounesios" <contovob@tcd.ie> > Date: Thu, 10 May 2018 03:54:27 +0100 > Cc: emacs-devel@gnu.org > > I forgot to ask in my previous email whether the duplicate > ';;; Custom Themes' headings in custom.el are intentional, and if not > how they might be better shuffled around. The first one is a pasto, and should be removed. ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Byte-compilation of custom themes 2018-05-10 2:49 ` Basil L. Contovounesios 2018-05-10 2:54 ` Basil L. Contovounesios @ 2018-05-11 14:02 ` Eli Zaretskii 2018-05-11 15:16 ` Basil L. Contovounesios 1 sibling, 1 reply; 33+ messages in thread From: Eli Zaretskii @ 2018-05-11 14:02 UTC (permalink / raw To: Basil L. Contovounesios; +Cc: monnier, emacs-devel > From: "Basil L. Contovounesios" <contovob@tcd.ie> > Date: Thu, 10 May 2018 03:49:35 +0100 > Cc: emacs-devel@gnu.org > > diff --git a/lisp/custom.el b/lisp/custom.el > index 1fed5dce53..b286f49ff9 100644 > --- a/lisp/custom.el > +++ b/lisp/custom.el > @@ -1299,17 +1299,15 @@ custom-available-themes > loaded, and no effort is made to check that the files contain > valid Custom themes. For a list of loaded themes, check the > variable `custom-known-themes'." > - (let (sym themes) > + (let ((suffix "-theme\\.el\\'") > + themes) > (dolist (dir (custom-theme--load-path)) > - (when (file-directory-p dir) > - (dolist (file (file-expand-wildcards > - (expand-file-name "*-theme.el" dir) t)) > - (setq file (file-name-nondirectory file)) > - (and (string-match "\\`\\(.+\\)-theme.el\\'" file) > - (setq sym (intern (match-string 1 file))) > - (custom-theme-name-valid-p sym) > - (push sym themes))))) > - (nreverse (delete-dups themes)))) > + (dolist (file (directory-files dir nil suffix)) The original code carefully verified that the members in custom-theme--load-path are directories, whereas your proposal calls directory-files on each member unconditionally, which will barf if a file is not a directory. > - (define-key map "\C-x\C-s" 'custom-theme-write) > - (define-key map "q" 'Custom-buffer-done) > - (define-key map "n" 'widget-forward) > - (define-key map "p" 'widget-backward) > + (define-key map "\C-x\C-s" #'custom-theme-write) > + (define-key map "q" #'Custom-buffer-done) > + (define-key map "n" #'widget-forward) > + (define-key map "p" #'widget-backward) Really? Are we going to switch to #'foo even in key bindings? > diff --git a/lisp/custom.el b/lisp/custom.el > index b8004cfd74..ae917c0292 100644 > --- a/lisp/custom.el > +++ b/lisp/custom.el > @@ -633,14 +633,10 @@ custom-load-symbol > (let ((custom-load-recursion t)) > ;; Load these files if not already done, > ;; to make sure we know all the dependencies of SYMBOL. > - (condition-case nil > - (require 'cus-load) > - (error nil)) > - (condition-case nil > - (require 'cus-start) > - (error nil)) > + (require 'cus-load nil t) > + (require 'cus-start nil t) > (dolist (load (get symbol 'custom-loads)) > - (cond ((symbolp load) (condition-case nil (require load) (error nil))) > + (cond ((symbolp load) (require load nil t)) > ;; This is subsumed by the test below, but it's much faster. > ((assoc load load-history)) > ;; This was just (assoc (locate-library load) load-history) > @@ -658,7 +654,7 @@ custom-load-symbol > ;; We are still loading it when we call this, > ;; and it is not in load-history yet. > ((equal load "cus-edit")) > - (t (condition-case nil (load load) (error nil)))))))) > + (t (load load t))))))) Why are we dropping the safety nets here? Thanks. ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Byte-compilation of custom themes 2018-05-11 14:02 ` Eli Zaretskii @ 2018-05-11 15:16 ` Basil L. Contovounesios 2018-05-11 16:03 ` Stefan Monnier 2018-05-11 17:32 ` Eli Zaretskii 0 siblings, 2 replies; 33+ messages in thread From: Basil L. Contovounesios @ 2018-05-11 15:16 UTC (permalink / raw To: Eli Zaretskii; +Cc: monnier, emacs-devel [-- Attachment #1: Type: text/plain, Size: 3870 bytes --] Eli Zaretskii <eliz@gnu.org> writes: >> From: "Basil L. Contovounesios" <contovob@tcd.ie> >> Date: Thu, 10 May 2018 03:49:35 +0100 >> Cc: emacs-devel@gnu.org >> >> diff --git a/lisp/custom.el b/lisp/custom.el >> index 1fed5dce53..b286f49ff9 100644 >> --- a/lisp/custom.el >> +++ b/lisp/custom.el >> @@ -1299,17 +1299,15 @@ custom-available-themes >> loaded, and no effort is made to check that the files contain >> valid Custom themes. For a list of loaded themes, check the >> variable `custom-known-themes'." >> - (let (sym themes) >> + (let ((suffix "-theme\\.el\\'") >> + themes) >> (dolist (dir (custom-theme--load-path)) >> - (when (file-directory-p dir) >> - (dolist (file (file-expand-wildcards >> - (expand-file-name "*-theme.el" dir) t)) >> - (setq file (file-name-nondirectory file)) >> - (and (string-match "\\`\\(.+\\)-theme.el\\'" file) >> - (setq sym (intern (match-string 1 file))) >> - (custom-theme-name-valid-p sym) >> - (push sym themes))))) >> - (nreverse (delete-dups themes)))) >> + (dolist (file (directory-files dir nil suffix)) > > The original code carefully verified that the members in > custom-theme--load-path are directories, whereas your proposal calls > directory-files on each member unconditionally, which will barf if a > file is not a directory. The function custom-theme--load-path already incorporates the file-directory-p check, so it is technically redundant here. Would you rather it be kept regardless? >> - (define-key map "\C-x\C-s" 'custom-theme-write) >> - (define-key map "q" 'Custom-buffer-done) >> - (define-key map "n" 'widget-forward) >> - (define-key map "p" 'widget-backward) >> + (define-key map "\C-x\C-s" #'custom-theme-write) >> + (define-key map "q" #'Custom-buffer-done) >> + (define-key map "n" #'widget-forward) >> + (define-key map "p" #'widget-backward) > > Really? Are we going to switch to #'foo even in key bindings? Though I personally prefer to consistently #'-quote function symbols in my own code, both for the extra byte-compiler check and narrower in-buffer completion, I have no strong opinion here; I was simply making the change in a sweeping fashion, in line with what I had perceived as a welcome style. Out of curiosity, though, what makes key bindings special w.r.t. quoting? >> diff --git a/lisp/custom.el b/lisp/custom.el >> index b8004cfd74..ae917c0292 100644 >> --- a/lisp/custom.el >> +++ b/lisp/custom.el >> @@ -633,14 +633,10 @@ custom-load-symbol >> (let ((custom-load-recursion t)) >> ;; Load these files if not already done, >> ;; to make sure we know all the dependencies of SYMBOL. >> - (condition-case nil >> - (require 'cus-load) >> - (error nil)) >> - (condition-case nil >> - (require 'cus-start) >> - (error nil)) >> + (require 'cus-load nil t) >> + (require 'cus-start nil t) >> (dolist (load (get symbol 'custom-loads)) >> - (cond ((symbolp load) (condition-case nil (require load) (error nil))) >> + (cond ((symbolp load) (require load nil t)) >> ;; This is subsumed by the test below, but it's much faster. >> ((assoc load load-history)) >> ;; This was just (assoc (locate-library load) load-history) >> @@ -658,7 +654,7 @@ custom-load-symbol >> ;; We are still loading it when we call this, >> ;; and it is not in load-history yet. >> ((equal load "cus-edit")) >> - (t (condition-case nil (load load) (error nil)))))))) >> + (t (load load t))))))) > > Why are we dropping the safety nets here? Because it hadn't occurred to silly us that we might want to additionally protect against evaluation errors. I reattach the patches, updated for the last two points of feedback and to remove the duplicate 'Custom Themes' heading. Thanks, -- Basil [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: 0001-Improve-loading-of-byte-compiled-custom-themes.patch --] [-- Type: text/x-diff, Size: 4290 bytes --] From 9fab63a6d4eb89fa0c0728fb93c13c7ee63524bc Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Wed, 9 May 2018 22:20:47 +0100 Subject: [PATCH 1/8] Improve loading of byte-compiled custom themes * lisp/custom.el (load-theme): Load byte-compiled file of safe themes when available. https://lists.gnu.org/archive/html/emacs-devel/2018-01/msg00614.html https://lists.gnu.org/archive/html/emacs-devel/2018-02/msg00060.html --- lisp/custom.el | 78 ++++++++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 37 deletions(-) diff --git a/lisp/custom.el b/lisp/custom.el index b7539685a8..1fed5dce53 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -1221,43 +1221,47 @@ load-theme (put theme 'theme-settings nil) (put theme 'theme-feature nil) (put theme 'theme-documentation nil)) - (let ((fn (locate-file (concat (symbol-name theme) "-theme.el") - (custom-theme--load-path) - '("" "c")))) - (unless fn - (error "Unable to find theme file for `%s'" theme)) - (with-temp-buffer - (insert-file-contents fn) - ;; Check file safety with `custom-safe-themes', prompting the - ;; user if necessary. - (when (or no-confirm - (eq custom-safe-themes t) - (and (memq 'default custom-safe-themes) - (equal (file-name-directory fn) - (expand-file-name "themes/" data-directory))) - (let ((hash (secure-hash 'sha256 (current-buffer)))) - (or (member hash custom-safe-themes) - (custom-theme-load-confirm hash)))) - (let ((custom--inhibit-theme-enable t) - (buffer-file-name fn)) ;For load-history. - (eval-buffer)) - ;; Optimization: if the theme changes the `default' face, put that - ;; entry first. This avoids some `frame-set-background-mode' rigmarole - ;; by assigning the new background immediately. - (let* ((settings (get theme 'theme-settings)) - (tail settings) - found) - (while (and tail (not found)) - (and (eq (nth 0 (car tail)) 'theme-face) - (eq (nth 1 (car tail)) 'default) - (setq found (car tail))) - (setq tail (cdr tail))) - (if found - (put theme 'theme-settings (cons found (delq found settings))))) - ;; Finally, enable the theme. - (unless no-enable - (enable-theme theme)) - t)))) + (let ((file (locate-file (concat (symbol-name theme) "-theme.el") + (custom-theme--load-path) + '("" "c"))) + (custom--inhibit-theme-enable t)) + ;; Check file safety with `custom-safe-themes', prompting the + ;; user if necessary. + (cond ((not file) + (error "Unable to find theme file for `%s'" theme)) + ((or no-confirm + (eq custom-safe-themes t) + (and (memq 'default custom-safe-themes) + (equal (file-name-directory file) + (expand-file-name "themes/" data-directory)))) + ;; Theme is safe; load byte-compiled version if available. + (load (file-name-sans-extension file) nil t nil t)) + ((with-temp-buffer + (insert-file-contents file) + (let ((hash (secure-hash 'sha256 (current-buffer)))) + (when (or (member hash custom-safe-themes) + (custom-theme-load-confirm hash)) + (eval-buffer nil nil file) + t)))) + (t + (error "Unable to load theme `%s'" theme)))) + ;; Optimization: if the theme changes the `default' face, put that + ;; entry first. This avoids some `frame-set-background-mode' rigmarole + ;; by assigning the new background immediately. + (let* ((settings (get theme 'theme-settings)) + (tail settings) + found) + (while (and tail (not found)) + (and (eq (nth 0 (car tail)) 'theme-face) + (eq (nth 1 (car tail)) 'default) + (setq found (car tail))) + (setq tail (cdr tail))) + (when found + (put theme 'theme-settings (cons found (delq found settings))))) + ;; Finally, enable the theme. + (unless no-enable + (enable-theme theme)) + t) (defun custom-theme-load-confirm (hash) "Query the user about loading a Custom theme that may not be safe. -- 2.17.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #3: 0002-Disable-no-byte-compile-in-built-in-themes.patch --] [-- Type: text/x-diff, Size: 6291 bytes --] From 8cb0bbce4dc574fdf458f528a4c30e48c9291c38 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Wed, 9 May 2018 22:30:48 +0100 Subject: [PATCH 2/8] Disable no-byte-compile in built-in themes * etc/themes/adwaita-theme.el: * etc/themes/deeper-blue-theme.el: * etc/themes/dichromacy-theme.el: * etc/themes/leuven-theme.el: * etc/themes/light-blue-theme.el: * etc/themes/manoj-dark-theme.el: * etc/themes/misterioso-theme.el: * etc/themes/tango-dark-theme.el: * etc/themes/tango-theme.el: * etc/themes/tsdh-dark-theme.el: * etc/themes/tsdh-light-theme.el: * etc/themes/wheatgrass-theme.el: * etc/themes/whiteboard-theme.el: * etc/themes/wombat-theme.el: Disable no-byte-compile. https://lists.gnu.org/archive/html/emacs-devel/2018-01/msg00614.html https://lists.gnu.org/archive/html/emacs-devel/2018-02/msg00060.html --- etc/themes/adwaita-theme.el | 4 ---- etc/themes/deeper-blue-theme.el | 4 ---- etc/themes/dichromacy-theme.el | 4 ---- etc/themes/leuven-theme.el | 1 - etc/themes/light-blue-theme.el | 4 ---- etc/themes/manoj-dark-theme.el | 4 ---- etc/themes/misterioso-theme.el | 4 ---- etc/themes/tango-dark-theme.el | 4 ---- etc/themes/tango-theme.el | 4 ---- etc/themes/tsdh-dark-theme.el | 4 ---- etc/themes/tsdh-light-theme.el | 5 ----- etc/themes/wheatgrass-theme.el | 4 ---- etc/themes/whiteboard-theme.el | 4 ---- etc/themes/wombat-theme.el | 4 ---- 14 files changed, 54 deletions(-) diff --git a/etc/themes/adwaita-theme.el b/etc/themes/adwaita-theme.el index b376153510..415db8a191 100644 --- a/etc/themes/adwaita-theme.el +++ b/etc/themes/adwaita-theme.el @@ -99,8 +99,4 @@ adwaita `(diff-added ((,class (:bold t :foreground "#4E9A06")))) `(diff-removed ((,class (:bold t :foreground "#F5666D")))))) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; adwaita-theme.el ends here diff --git a/etc/themes/deeper-blue-theme.el b/etc/themes/deeper-blue-theme.el index c6aa1751f4..0700f4f23d 100644 --- a/etc/themes/deeper-blue-theme.el +++ b/etc/themes/deeper-blue-theme.el @@ -110,8 +110,4 @@ deeper-blue (provide-theme 'deeper-blue) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; deeper-blue-theme.el ends here diff --git a/etc/themes/dichromacy-theme.el b/etc/themes/dichromacy-theme.el index 793209c055..bfced43aee 100644 --- a/etc/themes/dichromacy-theme.el +++ b/etc/themes/dichromacy-theme.el @@ -122,8 +122,4 @@ dichromacy (provide-theme 'dichromacy) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; dichromacy-theme.el ends here diff --git a/etc/themes/leuven-theme.el b/etc/themes/leuven-theme.el index 5c0d19ce81..c3c666588b 100644 --- a/etc/themes/leuven-theme.el +++ b/etc/themes/leuven-theme.el @@ -708,7 +708,6 @@ leuven ;; time-stamp-format: "%:y%02m%02d.%02H%02M" ;; time-stamp-start: "Version: " ;; time-stamp-end: "$" -;; no-byte-compile: t ;; End: ;;; leuven-theme.el ends here diff --git a/etc/themes/light-blue-theme.el b/etc/themes/light-blue-theme.el index 9935c565fb..ba00db6a49 100644 --- a/etc/themes/light-blue-theme.el +++ b/etc/themes/light-blue-theme.el @@ -61,8 +61,4 @@ light-blue (provide-theme 'light-blue) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; light-blue-theme.el ends here diff --git a/etc/themes/manoj-dark-theme.el b/etc/themes/manoj-dark-theme.el index fe61441d78..ddcaa0bd99 100644 --- a/etc/themes/manoj-dark-theme.el +++ b/etc/themes/manoj-dark-theme.el @@ -700,8 +700,4 @@ manoj-dark (provide-theme 'manoj-dark) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; manoj-dark.el ends here diff --git a/etc/themes/misterioso-theme.el b/etc/themes/misterioso-theme.el index 42e448d28b..6c1eec0f42 100644 --- a/etc/themes/misterioso-theme.el +++ b/etc/themes/misterioso-theme.el @@ -103,8 +103,4 @@ misterioso (provide-theme 'misterioso) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; misterioso-theme.el ends here diff --git a/etc/themes/tango-dark-theme.el b/etc/themes/tango-dark-theme.el index 3b6eeb702e..dae77a5e62 100644 --- a/etc/themes/tango-dark-theme.el +++ b/etc/themes/tango-dark-theme.el @@ -170,8 +170,4 @@ tango-dark (provide-theme 'tango-dark) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; tango-dark-theme.el ends here diff --git a/etc/themes/tango-theme.el b/etc/themes/tango-theme.el index a7a79c04ad..4fe2480bc7 100644 --- a/etc/themes/tango-theme.el +++ b/etc/themes/tango-theme.el @@ -154,8 +154,4 @@ tango (provide-theme 'tango) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; tango-theme.el ends here diff --git a/etc/themes/tsdh-dark-theme.el b/etc/themes/tsdh-dark-theme.el index 287fef8253..c216750cb2 100644 --- a/etc/themes/tsdh-dark-theme.el +++ b/etc/themes/tsdh-dark-theme.el @@ -144,8 +144,4 @@ tsdh-dark (provide-theme 'tsdh-dark) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; tsdh-dark-theme.el ends here diff --git a/etc/themes/tsdh-light-theme.el b/etc/themes/tsdh-light-theme.el index 17a86fdbfe..ce9d1a2c3c 100644 --- a/etc/themes/tsdh-light-theme.el +++ b/etc/themes/tsdh-light-theme.el @@ -106,9 +106,4 @@ tsdh-light (provide-theme 'tsdh-light) - -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; tsdh-light-theme.el ends here diff --git a/etc/themes/wheatgrass-theme.el b/etc/themes/wheatgrass-theme.el index 9585e3aa6e..8d34c28bf4 100644 --- a/etc/themes/wheatgrass-theme.el +++ b/etc/themes/wheatgrass-theme.el @@ -83,8 +83,4 @@ wheatgrass (provide-theme 'wheatgrass) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; wheatgrass-theme.el ends here diff --git a/etc/themes/whiteboard-theme.el b/etc/themes/whiteboard-theme.el index 5db0ddd68d..fe46cb0928 100644 --- a/etc/themes/whiteboard-theme.el +++ b/etc/themes/whiteboard-theme.el @@ -100,8 +100,4 @@ whiteboard (provide-theme 'whiteboard) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; whiteboard-theme.el ends here diff --git a/etc/themes/wombat-theme.el b/etc/themes/wombat-theme.el index 583b8dc3f6..00f29bb9fa 100644 --- a/etc/themes/wombat-theme.el +++ b/etc/themes/wombat-theme.el @@ -102,8 +102,4 @@ wombat (provide-theme 'wombat) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; wombat-theme.el ends here -- 2.17.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #4: 0003-Fix-custom-available-themes-file-expansion.patch --] [-- Type: text/x-diff, Size: 1642 bytes --] From e2e1dd4834536d439600ec0db3a4ec061408d821 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Wed, 2 May 2018 21:18:24 +0100 Subject: [PATCH 3/8] Fix custom-available-themes file expansion * lisp/custom.el: (custom-available-themes): Use directory-files instead of performing arbitrary wildcard expansion in filenames. --- lisp/custom.el | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/lisp/custom.el b/lisp/custom.el index 1fed5dce53..b286f49ff9 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -1299,17 +1299,15 @@ custom-available-themes loaded, and no effort is made to check that the files contain valid Custom themes. For a list of loaded themes, check the variable `custom-known-themes'." - (let (sym themes) + (let ((suffix "-theme\\.el\\'") + themes) (dolist (dir (custom-theme--load-path)) - (when (file-directory-p dir) - (dolist (file (file-expand-wildcards - (expand-file-name "*-theme.el" dir) t)) - (setq file (file-name-nondirectory file)) - (and (string-match "\\`\\(.+\\)-theme.el\\'" file) - (setq sym (intern (match-string 1 file))) - (custom-theme-name-valid-p sym) - (push sym themes))))) - (nreverse (delete-dups themes)))) + (dolist (file (directory-files dir nil suffix)) + (let ((theme (intern (substring file 0 (string-match-p suffix file))))) + (and (custom-theme-name-valid-p theme) + (not (memq theme themes)) + (push theme themes))))) + (nreverse themes))) (defun custom-theme--load-path () (let (lpath) -- 2.17.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #5: 0004-lisp-custom.el-Use-lexical-binding.patch --] [-- Type: text/x-diff, Size: 7797 bytes --] From 469db438763a31e49cf2d0ca2925a835954d910c Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Fri, 11 May 2018 16:09:57 +0100 Subject: [PATCH 4/8] * lisp/custom.el: Use lexical-binding Remove duplicate 'Custom Themes' comment heading. (deftheme, custom-declare-theme): Fix advertised calling convention. (custom-enabled-themes): Fix message grammar. --- lisp/custom.el | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/lisp/custom.el b/lisp/custom.el index b286f49ff9..aa201e3331 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -1,4 +1,4 @@ -;;; custom.el --- tools for declaring and initializing options +;;; custom.el --- tools for declaring and initializing options -*- lexical-binding: t -*- ;; ;; Copyright (C) 1996-1997, 1999, 2001-2018 Free Software Foundation, ;; Inc. @@ -150,7 +150,7 @@ custom-declare-variable (put symbol 'force-value nil)) (if (keywordp doc) (error "Doc string is missing")) - (let ((initialize 'custom-initialize-reset) + (let ((initialize #'custom-initialize-reset) (requests nil)) (unless (memq :group args) (custom-add-to-group (custom-current-group) symbol 'custom-variable)) @@ -426,7 +426,7 @@ custom-current-group (defun custom-declare-group (symbol members doc &rest args) "Like `defgroup', but SYMBOL is evaluated as a normal argument." (while members - (apply 'custom-add-to-group symbol (car members)) + (apply #'custom-add-to-group symbol (car members)) (setq members (cdr members))) (when doc ;; This text doesn't get into DOC. @@ -618,11 +618,8 @@ custom-note-var-changed The result is that the change is treated as having been made through Custom." (put variable 'customized-value (list (custom-quote (eval variable))))) -\f -;;; Custom Themes - -;;; Loading files needed to customize a symbol. -;;; This is in custom.el because menu-bar.el needs it for toggle cmds. +;; Loading files needed to customize a symbol. +;; This is in custom.el because menu-bar.el needs it for toggle cmds. (defvar custom-load-recursion nil "Hack to avoid recursive dependencies.") @@ -715,7 +712,7 @@ customize-mark-to-save Return non-nil if the `saved-value' property actually changed." (custom-load-symbol symbol) - (let* ((get (or (get symbol 'custom-get) 'default-value)) + (let* ((get (or (get symbol 'custom-get) #'default-value)) (value (funcall get symbol)) (saved (get symbol 'saved-value)) (standard (get symbol 'standard-value)) @@ -744,7 +741,7 @@ customize-mark-as-set Return non-nil if the `customized-value' property actually changed." (custom-load-symbol symbol) - (let* ((get (or (get symbol 'custom-get) 'default-value)) + (let* ((get (or (get symbol 'custom-get) #'default-value)) (value (funcall get symbol)) (customized (get symbol 'customized-value)) (old (or (get symbol 'saved-value) (get symbol 'standard-value)))) @@ -776,7 +773,7 @@ custom-reevaluate-setting ;; always do the funcall step, even if symbol was not bound before. (or (default-boundp symbol) (eval `(defvar ,symbol nil))) ; reset below, so any value is fine - (funcall (or (get symbol 'custom-set) 'set-default) + (funcall (or (get symbol 'custom-set) #'set-default) symbol (eval (car (or (get symbol 'saved-value) (get symbol 'standard-value)))))) @@ -941,7 +938,7 @@ custom-set-variables REQUEST is a list of features we must require in order to handle SYMBOL properly. COMMENT is a comment string about SYMBOL." - (apply 'custom-theme-set-variables 'user args)) + (apply #'custom-theme-set-variables 'user args)) (defun custom-theme-set-variables (theme &rest args) "Initialize variables for theme THEME according to settings in ARGS. @@ -989,8 +986,8 @@ custom-theme-set-variables set) (when requests (put symbol 'custom-requests requests) - (mapc 'require requests)) - (setq set (or (get symbol 'custom-set) 'custom-set-default)) + (mapc #'require requests)) + (setq set (or (get symbol 'custom-set) #'custom-set-default)) (put symbol 'saved-value (list value)) (put symbol 'saved-variable-comment comment) ;; Allow for errors in the case where the setter has @@ -1086,26 +1083,29 @@ custom--sort-vars-1 ;; they were used to supply keyword-value pairs like `:immediate', ;; `:variable-reset-string', etc. We don't use any of these, so ignore them. -(defmacro deftheme (theme &optional doc &rest ignored) +(defmacro deftheme (theme &optional doc &rest _ignored) "Declare THEME to be a Custom theme. The optional argument DOC is a doc string describing the theme. Any theme `foo' should be defined in a file called `foo-theme.el'; see `custom-make-theme-feature' for more information." - (declare (doc-string 2)) + (declare (doc-string 2) + (advertised-calling-convention (theme &optional doc) "22.1")) (let ((feature (custom-make-theme-feature theme))) ;; It is better not to use backquote in this file, ;; because that makes a bootstrapping problem ;; if you need to recompile all the Lisp files using interpreted code. (list 'custom-declare-theme (list 'quote theme) (list 'quote feature) doc))) -(defun custom-declare-theme (theme feature &optional doc &rest ignored) +(defun custom-declare-theme (theme feature &optional doc &rest _ignored) "Like `deftheme', but THEME is evaluated as a normal argument. FEATURE is the feature this theme provides. Normally, this is a symbol created from THEME by `custom-make-theme-feature'." + (declare (advertised-calling-convention (theme feature &optional doc) "22.1")) (unless (custom-theme-name-valid-p theme) (error "Custom theme cannot be named %S" theme)) - (add-to-list 'custom-known-themes theme) + (unless (memq theme custom-known-themes) + (push theme custom-known-themes)) (put theme 'theme-feature feature) (when doc (put theme 'theme-documentation doc))) @@ -1206,7 +1206,7 @@ load-theme (interactive (list (intern (completing-read "Load custom theme: " - (mapcar 'symbol-name + (mapcar #'symbol-name (custom-available-themes)))) nil nil)) (unless (custom-theme-name-valid-p theme) @@ -1387,9 +1387,9 @@ custom-enabled-themes themes (delq theme themes))))) (enable-theme 'user) (custom-set-default symbol themes) - (if failures - (message "Failed to enable theme: %s" - (mapconcat 'symbol-name failures ", ")))))) + (when failures + (message "Failed to enable theme(s): %s" + (mapconcat #'symbol-name failures ", ")))))) (defsubst custom-theme-enabled-p (theme) "Return non-nil if THEME is enabled." @@ -1401,7 +1401,7 @@ disable-theme (interactive (list (intern (completing-read "Disable custom theme: " - (mapcar 'symbol-name custom-enabled-themes) + (mapcar #'symbol-name custom-enabled-themes) nil t)))) (when (custom-theme-enabled-p theme) (let ((settings (get theme 'theme-settings))) @@ -1467,7 +1467,7 @@ custom-theme-recalc-variable (if (and valspec (or (get variable 'force-value) (default-boundp variable))) - (funcall (or (get variable 'custom-set) 'set-default) variable + (funcall (or (get variable 'custom-set) #'set-default) variable (eval (car valspec)))))) (defun custom-theme-recalc-face (face) @@ -1508,7 +1508,7 @@ custom-reset-variables (VARIABLE IGNORED) This means reset VARIABLE. (The argument IGNORED is ignored)." - (apply 'custom-theme-reset-variables 'user args)) + (apply #'custom-theme-reset-variables 'user args)) ;;; The End. -- 2.17.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #6: 0005-lisp-cus-theme.el-Use-lexical-binding.patch --] [-- Type: text/x-diff, Size: 5907 bytes --] From 53e0f80510a6a5d0923a8e60627f3a8ba3239c0f Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Fri, 11 May 2018 15:35:09 +0100 Subject: [PATCH 5/8] * lisp/cus-theme.el: Use lexical-binding --- lisp/cus-theme.el | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/lisp/cus-theme.el b/lisp/cus-theme.el index e5e787771b..53389956ad 100644 --- a/lisp/cus-theme.el +++ b/lisp/cus-theme.el @@ -1,4 +1,4 @@ -;;; cus-theme.el -- custom theme creation user interface +;;; cus-theme.el -- custom theme creation user interface -*- lexical-binding: t -*- ;; ;; Copyright (C) 2001-2018 Free Software Foundation, Inc. ;; @@ -47,7 +47,7 @@ custom-new-theme-mode Do not call this mode function yourself. It is meant for internal use." (use-local-map custom-new-theme-mode-map) (custom--initialize-widget-variables) - (set (make-local-variable 'revert-buffer-function) 'custom-theme-revert)) + (set (make-local-variable 'revert-buffer-function) #'custom-theme-revert)) (put 'custom-new-theme-mode 'mode-class 'special) (defvar custom-theme-name nil) @@ -118,13 +118,13 @@ customize-create-theme :tag " Visit Theme " :help-echo "Insert the settings of a pre-defined theme." :action (lambda (_widget &optional _event) - (call-interactively 'custom-theme-visit-theme))) + (call-interactively #'custom-theme-visit-theme))) (widget-insert " ") (widget-create 'push-button :tag " Merge Theme " :help-echo "Merge in the settings of a pre-defined theme." :action (lambda (_widget &optional _event) - (call-interactively 'custom-theme-merge-theme))) + (call-interactively #'custom-theme-merge-theme))) (widget-insert " ") (widget-create 'push-button :tag " Revert " @@ -142,7 +142,7 @@ customize-create-theme (widget-create 'text :value (format-time-string "Created %Y-%m-%d."))) (widget-create 'push-button - :notify (function custom-theme-write) + :notify #'custom-theme-write " Save Theme ") (when (eq theme 'user) (setq custom-theme--migrate-settings t) @@ -188,7 +188,7 @@ customize-create-theme :mouse-face 'highlight :pressed-face 'highlight :action (lambda (_widget &optional _event) - (call-interactively 'custom-theme-add-face))) + (call-interactively #'custom-theme-add-face))) ;; If THEME is non-nil, insert all of that theme's variables. (widget-insert "\n\n Theme variables:\n ") @@ -207,7 +207,7 @@ customize-create-theme :mouse-face 'highlight :pressed-face 'highlight :action (lambda (_widget &optional _event) - (call-interactively 'custom-theme-add-variable))) + (call-interactively #'custom-theme-add-variable))) (widget-insert ?\n) (widget-setup) (goto-char (point-min)) @@ -254,7 +254,7 @@ custom-theme-add-var-1 :tag (custom-unlispify-tag-name symbol) :value symbol :shown-value (list val) - :notify 'ignore + :notify #'ignore :custom-level 0 :custom-state 'hidden :custom-style 'simple)) @@ -313,7 +313,7 @@ custom-theme-visit-theme (interactive (list (intern (completing-read "Find custom theme: " - (mapcar 'symbol-name + (mapcar #'symbol-name (custom-available-themes)))))) (unless (custom-theme-name-valid-p theme) (error "No valid theme named `%s'" theme)) @@ -328,7 +328,7 @@ custom-theme-merge-theme (interactive (list (intern (completing-read "Merge custom theme: " - (mapcar 'symbol-name + (mapcar #'symbol-name (custom-available-themes)))))) (unless (eq theme 'user) (unless (custom-theme-name-valid-p theme) @@ -343,8 +343,8 @@ custom-theme-merge-theme (memq name '(custom-enabled-themes custom-safe-themes))) (funcall (if option - 'custom-theme-add-variable - 'custom-theme-add-face) + #'custom-theme-add-variable + #'custom-theme-add-face) name value))))) theme) @@ -475,7 +475,7 @@ describe-theme (interactive (list (intern (completing-read "Describe custom theme: " - (mapcar 'symbol-name + (mapcar #'symbol-name (custom-available-themes)))))) (unless (custom-theme-name-valid-p theme) (error "Invalid theme name `%s'" theme)) @@ -616,11 +616,11 @@ customize-themes (widget-create 'push-button :tag " Save Theme Settings " :help-echo "Save the selected themes for future sessions." - :action 'custom-theme-save) + :action #'custom-theme-save) (widget-insert ?\n) (widget-create 'checkbox :value custom-theme-allow-multiple-selections - :action 'custom-theme-selections-toggle) + :action #'custom-theme-selections-toggle) (widget-insert (propertize " Select more than one theme at a time" 'face '(variable-pitch (:height 0.9)))) @@ -632,13 +632,13 @@ customize-themes :value (custom-theme-enabled-p theme) :theme-name theme :help-echo help-echo - :action 'custom-theme-checkbox-toggle)) + :action #'custom-theme-checkbox-toggle)) (push (cons theme widget) custom--listed-themes) (widget-create-child-and-convert widget 'push-button :button-face-get 'ignore :mouse-face-get 'ignore :value (format " %s" theme) - :action 'widget-parent-action + :action #'widget-parent-action :help-echo help-echo) (widget-insert " -- " (propertize (custom-theme-summary theme) -- 2.17.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #7: 0006-Minor-custom.el-simplifications.patch --] [-- Type: text/x-diff, Size: 7932 bytes --] From b67f5d3b2022ed7e4e5eb6085a62c218d142f244 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Fri, 11 May 2018 15:46:39 +0100 Subject: [PATCH 6/8] Minor custom.el simplifications * lisp/custom.el (custom-quote): Duplicate macroexp-quote. (custom-load-symbol, customize-mark-to-save, customize-mark-as-set) (custom-theme-name-valid-p, enable-theme, custom-enabled-themes) (disable-theme): Simplify logic. --- lisp/custom.el | 104 ++++++++++++++++++++++--------------------------- 1 file changed, 47 insertions(+), 57 deletions(-) diff --git a/lisp/custom.el b/lisp/custom.el index aa201e3331..b3311a1783 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -630,14 +630,12 @@ custom-load-symbol (let ((custom-load-recursion t)) ;; Load these files if not already done, ;; to make sure we know all the dependencies of SYMBOL. - (condition-case nil - (require 'cus-load) - (error nil)) - (condition-case nil - (require 'cus-start) - (error nil)) + (ignore-errors + (require 'cus-load)) + (ignore-errors + (require 'cus-start)) (dolist (load (get symbol 'custom-loads)) - (cond ((symbolp load) (condition-case nil (require load) (error nil))) + (cond ((symbolp load) (ignore-errors (require load))) ;; This is subsumed by the test below, but it's much faster. ((assoc load load-history)) ;; This was just (assoc (locate-library load) load-history) @@ -655,7 +653,7 @@ custom-load-symbol ;; We are still loading it when we call this, ;; and it is not in load-history yet. ((equal load "cus-edit")) - (t (condition-case nil (load load) (error nil)))))))) + (t (ignore-errors (load load)))))))) \f (defvar custom-local-buffer nil "Non-nil, in a Customization buffer, means customize a specific buffer. @@ -688,16 +686,12 @@ custom-set-minor-mode (defun custom-quote (sexp) "Quote SEXP if it is not self quoting." - (if (or (memq sexp '(t nil)) - (keywordp sexp) - (and (listp sexp) - (memq (car sexp) '(lambda))) - (stringp sexp) - (numberp sexp) - (vectorp sexp) -;;; (and (fboundp 'characterp) -;;; (characterp sexp)) - ) + ;; Can't use `macroexp-quote' because it is loaded after `custom.el' + ;; during bootstrap. See `loadup.el'. + (if (and (not (consp sexp)) + (or (keywordp sexp) + (not (symbolp sexp)) + (booleanp sexp))) sexp (list 'quote sexp))) @@ -718,12 +712,11 @@ customize-mark-to-save (standard (get symbol 'standard-value)) (comment (get symbol 'customized-variable-comment))) ;; Save default value if different from standard value. - (if (or (null standard) - (not (equal value (condition-case nil - (eval (car standard)) - (error nil))))) - (put symbol 'saved-value (list (custom-quote value))) - (put symbol 'saved-value nil)) + (if (and standard + (equal value (ignore-errors + (eval (car standard))))) + (put symbol 'saved-value nil) + (put symbol 'saved-value (list (custom-quote value)))) ;; Clear customized information (set, but not saved). (put symbol 'customized-value nil) ;; Save any comment that might have been set. @@ -747,9 +740,8 @@ customize-mark-as-set (old (or (get symbol 'saved-value) (get symbol 'standard-value)))) ;; Mark default value as set if different from old value. (if (not (and old - (equal value (condition-case nil - (eval (car old)) - (error nil))))) + (equal value (ignore-errors + (eval (car old)))))) (progn (put symbol 'customized-value (list (custom-quote value))) (custom-push-theme 'theme-value symbol 'user 'set (custom-quote value))) @@ -1284,11 +1276,9 @@ custom-theme-load-confirm (defun custom-theme-name-valid-p (name) "Return t if NAME is a valid name for a Custom theme, nil otherwise. NAME should be a symbol." - (and (symbolp name) - name - (not (or (zerop (length (symbol-name name))) - (eq name 'user) - (eq name 'changed))))) + (and (not (memq name '(nil user changed))) + (symbolp name) + (not (string= "" (symbol-name name))))) (defun custom-available-themes () "Return a list of Custom themes available for loading. @@ -1332,8 +1322,8 @@ enable-theme (completing-read "Enable custom theme: " obarray (lambda (sym) (get sym 'theme-settings)) t)))) - (if (not (custom-theme-p theme)) - (error "Undefined Custom theme %s" theme)) + (unless (custom-theme-p theme) + (error "Undefined Custom theme %s" theme)) (let ((settings (get theme 'theme-settings))) ;; Loop through theme settings, recalculating vars/faces. (dolist (s settings) @@ -1373,18 +1363,18 @@ custom-enabled-themes (let (failures) (setq themes (delq 'user (delete-dups themes))) ;; Disable all themes not in THEMES. - (if (boundp symbol) - (dolist (theme (symbol-value symbol)) - (if (not (memq theme themes)) - (disable-theme theme)))) + (dolist (theme (and (boundp symbol) + (symbol-value symbol))) + (unless (memq theme themes) + (disable-theme theme))) ;; Call `enable-theme' or `load-theme' on each of THEMES. (dolist (theme (reverse themes)) (condition-case nil (if (custom-theme-p theme) (enable-theme theme) (load-theme theme)) - (error (setq failures (cons theme failures) - themes (delq theme themes))))) + (error (push theme failures) + (setq themes (delq theme themes))))) (enable-theme 'user) (custom-set-default symbol themes) (when failures @@ -1417,23 +1407,23 @@ disable-theme ;; If the face spec specified by this theme is in the ;; saved-face property, reset that property. (when (equal (nth 3 s) (get symbol 'saved-face)) - (put symbol 'saved-face (and val (cadr (car val))))))))) - ;; Recompute faces on all frames. - (dolist (frame (frame-list)) - ;; We must reset the fg and bg color frame parameters, or - ;; `face-set-after-frame-default' will use the existing - ;; parameters, which could be from the disabled theme. - (set-frame-parameter frame 'background-color - (custom--frame-color-default - frame :background "background" "Background" - "unspecified-bg" "white")) - (set-frame-parameter frame 'foreground-color - (custom--frame-color-default - frame :foreground "foreground" "Foreground" - "unspecified-fg" "black")) - (face-set-after-frame-default frame)) - (setq custom-enabled-themes - (delq theme custom-enabled-themes))))) + (put symbol 'saved-face (cadar val)))))))) + ;; Recompute faces on all frames. + (dolist (frame (frame-list)) + ;; We must reset the fg and bg color frame parameters, or + ;; `face-set-after-frame-default' will use the existing + ;; parameters, which could be from the disabled theme. + (set-frame-parameter frame 'background-color + (custom--frame-color-default + frame :background "background" "Background" + "unspecified-bg" "white")) + (set-frame-parameter frame 'foreground-color + (custom--frame-color-default + frame :foreground "foreground" "Foreground" + "unspecified-fg" "black")) + (face-set-after-frame-default frame)) + (setq custom-enabled-themes + (delq theme custom-enabled-themes)))) ;; Only used if window-system not null. (declare-function x-get-resource "frame.c" -- 2.17.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #8: 0007-Minor-cus-theme.el-simplifications.patch --] [-- Type: text/x-diff, Size: 3932 bytes --] From 3454df6cd6010358f2228a003d7d4adc0f3a704e Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Thu, 10 May 2018 03:08:10 +0100 Subject: [PATCH 7/8] Minor cus-theme.el simplifications * lisp/cus-theme.el (custom-new-theme-mode, customize-themes) (custom-theme-choose-mode): Use setq-local. (customize-create-theme): Ditto. Use delete-all-overlays. (describe-theme-1, custom-theme-summary): Simplify logic. --- lisp/cus-theme.el | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/lisp/cus-theme.el b/lisp/cus-theme.el index 53389956ad..995c55b2b2 100644 --- a/lisp/cus-theme.el +++ b/lisp/cus-theme.el @@ -47,7 +47,7 @@ custom-new-theme-mode Do not call this mode function yourself. It is meant for internal use." (use-local-map custom-new-theme-mode-map) (custom--initialize-widget-variables) - (set (make-local-variable 'revert-buffer-function) #'custom-theme-revert)) + (setq-local revert-buffer-function #'custom-theme-revert)) (put 'custom-new-theme-mode 'mode-class 'special) (defvar custom-theme-name nil) @@ -93,15 +93,14 @@ customize-create-theme (switch-to-buffer (get-buffer-create (or buffer "*Custom Theme*"))) (let ((inhibit-read-only t)) (erase-buffer) - (dolist (ov (overlays-in (point-min) (point-max))) - (delete-overlay ov))) + (delete-all-overlays)) (custom-new-theme-mode) (make-local-variable 'custom-theme-name) - (set (make-local-variable 'custom-theme--save-name) theme) - (set (make-local-variable 'custom-theme-faces) nil) - (set (make-local-variable 'custom-theme-variables) nil) - (set (make-local-variable 'custom-theme-description) "") - (set (make-local-variable 'custom-theme--migrate-settings) nil) + (setq-local custom-theme--save-name theme) + (setq-local custom-theme-faces nil) + (setq-local custom-theme-variables nil) + (setq-local custom-theme-description "") + (setq-local custom-theme--migrate-settings nil) (make-local-variable 'custom-theme-insert-face-marker) (make-local-variable 'custom-theme-insert-variable-marker) (make-local-variable 'custom-theme--listed-faces) @@ -513,8 +512,7 @@ describe-theme-1 (condition-case nil (read (current-buffer)) (end-of-file nil))))) - (and sexp (listp sexp) - (eq (car sexp) 'deftheme) + (and (eq (car-safe sexp) 'deftheme) (setq doc (nth 2 sexp))))))) (princ "\n\nDocumentation:\n") (princ (if (stringp doc) @@ -552,10 +550,10 @@ custom-theme-choose-mode Do not call this mode function yourself. It is meant for internal use." (use-local-map custom-theme-choose-mode-map) (custom--initialize-widget-variables) - (set (make-local-variable 'revert-buffer-function) - (lambda (_ignore-auto noconfirm) - (when (or noconfirm (y-or-n-p "Discard current choices? ")) - (customize-themes (current-buffer)))))) + (setq-local revert-buffer-function + (lambda (_ignore-auto noconfirm) + (when (or noconfirm (y-or-n-p "Discard current choices? ")) + (customize-themes (current-buffer)))))) (put 'custom-theme-choose-mode 'mode-class 'special) ;;;###autoload @@ -568,7 +566,7 @@ customize-themes (let ((inhibit-read-only t)) (erase-buffer)) (custom-theme-choose-mode) - (set (make-local-variable 'custom--listed-themes) nil) + (setq-local custom--listed-themes nil) (make-local-variable 'custom-theme-allow-multiple-selections) (and (null custom-theme-allow-multiple-selections) (> (length custom-enabled-themes) 1) @@ -662,8 +660,7 @@ custom-theme-summary (condition-case nil (read (current-buffer)) (end-of-file nil))))) - (and sexp (listp sexp) - (eq (car sexp) 'deftheme) + (and (eq (car-safe sexp) 'deftheme) (setq doc (nth 2 sexp)))))))) (cond ((null doc) "(no documentation available)") -- 2.17.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #9: 0008-Minor-subr-x-tweaks.patch --] [-- Type: text/x-diff, Size: 1193 bytes --] From 8e329124b0c869f3ca841d8f6fc2c885cd7b9126 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Thu, 3 May 2018 16:12:56 +0100 Subject: [PATCH 8/8] Minor subr-x tweaks * lisp/emacs-lisp/subr-x.el (string-join): #'-quote function symbol. (string-remove-suffix): One less call to length. --- lisp/emacs-lisp/subr-x.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el index 7fab9083e8..2ae31f593c 100644 --- a/lisp/emacs-lisp/subr-x.el +++ b/lisp/emacs-lisp/subr-x.el @@ -211,7 +211,7 @@ string-empty-p (defsubst string-join (strings &optional separator) "Join all STRINGS using SEPARATOR." - (mapconcat 'identity strings separator)) + (mapconcat #'identity strings separator)) (define-obsolete-function-alias 'string-reverse 'reverse "25.1") @@ -250,7 +250,7 @@ string-remove-prefix (defsubst string-remove-suffix (suffix string) "Remove SUFFIX from STRING if present." (if (string-suffix-p suffix string) - (substring string 0 (- (length string) (length suffix))) + (substring string 0 (- (length suffix))) string)) (provide 'subr-x) -- 2.17.0 ^ permalink raw reply related [flat|nested] 33+ messages in thread
* Re: Byte-compilation of custom themes 2018-05-11 15:16 ` Basil L. Contovounesios @ 2018-05-11 16:03 ` Stefan Monnier 2018-05-11 20:03 ` Basil L. Contovounesios 2018-05-11 17:32 ` Eli Zaretskii 1 sibling, 1 reply; 33+ messages in thread From: Stefan Monnier @ 2018-05-11 16:03 UTC (permalink / raw To: Eli Zaretskii; +Cc: emacs-devel > Though I personally prefer to consistently #'-quote function symbols in > my own code, both for the extra byte-compiler check and narrower > in-buffer completion, I have no strong opinion here; I was simply making > the change in a sweeping fashion, in line with what I had perceived as a > welcome style. Out of curiosity, though, what makes key bindings > special w.r.t. quoting? [ I'm probably responsible in large part for the recent popularity of the #' notation, so I figured I should chime in: ] While I generally prefer to use #' where applicable, I have resisted the temptation to use it in keymaps because I have found it leads to "spurious" warnings more often than in other contexts (and the impact of an invalid binding is also less serious than a call to a non-existing function). Also, to me #'f means "the function bound to this symbol" whereas 'f means "the symbol f", and in key-bindings I really want to use "the symbol" rather than "the associated function" because `C-h m` gives poor results when keys are bound to lambda expressions. It's a rather "philosophical" argument, tho. Stefan ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Byte-compilation of custom themes 2018-05-11 16:03 ` Stefan Monnier @ 2018-05-11 20:03 ` Basil L. Contovounesios 0 siblings, 0 replies; 33+ messages in thread From: Basil L. Contovounesios @ 2018-05-11 20:03 UTC (permalink / raw To: Stefan Monnier; +Cc: Eli Zaretskii, emacs-devel Stefan Monnier <monnier@IRO.UMontreal.CA> writes: > While I generally prefer to use #' where applicable, I have resisted the > temptation to use it in keymaps because I have found it leads to > "spurious" warnings more often than in other contexts (and the impact > of an invalid binding is also less serious than a call to > a non-existing function). Good point, thanks! > Also, to me #'f means "the function bound to this symbol" whereas 'f > means "the symbol f", and in key-bindings I really want to use "the > symbol" rather than "the associated function" because `C-h m` gives poor > results when keys are bound to lambda expressions. It's a rather > "philosophical" argument, tho. Agreed; too bad I live for philosophical discourse. ;) -- Basil ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Byte-compilation of custom themes 2018-05-11 15:16 ` Basil L. Contovounesios 2018-05-11 16:03 ` Stefan Monnier @ 2018-05-11 17:32 ` Eli Zaretskii 2018-05-11 20:43 ` Basil L. Contovounesios 1 sibling, 1 reply; 33+ messages in thread From: Eli Zaretskii @ 2018-05-11 17:32 UTC (permalink / raw To: Basil L. Contovounesios; +Cc: monnier, emacs-devel > From: "Basil L. Contovounesios" <contovob@tcd.ie> > Cc: <monnier@IRO.UMontreal.CA>, <emacs-devel@gnu.org> > Date: Fri, 11 May 2018 16:16:09 +0100 > > > The original code carefully verified that the members in > > custom-theme--load-path are directories, whereas your proposal calls > > directory-files on each member unconditionally, which will barf if a > > file is not a directory. > > The function custom-theme--load-path already incorporates the > file-directory-p check, so it is technically redundant here. > Would you rather it be kept regardless? We should at least have a comment there that we are relying on custom-theme--load-path to do the test, and perhaps also an assertion. > >> - (define-key map "\C-x\C-s" 'custom-theme-write) > >> - (define-key map "q" 'Custom-buffer-done) > >> - (define-key map "n" 'widget-forward) > >> - (define-key map "p" 'widget-backward) > >> + (define-key map "\C-x\C-s" #'custom-theme-write) > >> + (define-key map "q" #'Custom-buffer-done) > >> + (define-key map "n" #'widget-forward) > >> + (define-key map "p" #'widget-backward) > > > > Really? Are we going to switch to #'foo even in key bindings? > > Though I personally prefer to consistently #'-quote function symbols in > my own code, both for the extra byte-compiler check and narrower > in-buffer completion, I have no strong opinion here; I was simply making > the change in a sweeping fashion, in line with what I had perceived as a > welcome style. Out of curiosity, though, what makes key bindings > special w.r.t. quoting? Stefan gave one reason (with which I agree). From POV, it's another stab into my heart of a veteran reader of Emacs Lisp code. I recently find the code harder and harder to read due to all the new syntax and unfamiliar functions. You can ignore me on that, though. Thanks. ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Byte-compilation of custom themes 2018-05-11 17:32 ` Eli Zaretskii @ 2018-05-11 20:43 ` Basil L. Contovounesios 2018-05-12 7:04 ` Eli Zaretskii 0 siblings, 1 reply; 33+ messages in thread From: Basil L. Contovounesios @ 2018-05-11 20:43 UTC (permalink / raw To: Eli Zaretskii; +Cc: monnier, emacs-devel [-- Attachment #1: Type: text/plain, Size: 1206 bytes --] Eli Zaretskii <eliz@gnu.org> writes: >> From: "Basil L. Contovounesios" <contovob@tcd.ie> >> Cc: <monnier@IRO.UMontreal.CA>, <emacs-devel@gnu.org> >> Date: Fri, 11 May 2018 16:16:09 +0100 >> >> > The original code carefully verified that the members in >> > custom-theme--load-path are directories, whereas your proposal calls >> > directory-files on each member unconditionally, which will barf if a >> > file is not a directory. >> >> The function custom-theme--load-path already incorporates the >> file-directory-p check, so it is technically redundant here. >> Would you rather it be kept regardless? > > We should at least have a comment there that we are relying on > custom-theme--load-path to do the test, and perhaps also an assertion. Do you mean a cl-assertion, or an emulation thereof? E.g.: (unless (file-directory-p dir) (signal 'file-missing (list "`custom-theme-load-path'" "No such directory" dir))) (I'm unsure on the convention for file-missing errors.) Either way, what is the benefit of barfing before directory-files does? Wouldn't a docstring for custom-theme--load-path and a comment in custom-available-themes suffice for the reader (they do for me)? E.g.: [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: custom.diff --] [-- Type: text/x-diff, Size: 843 bytes --] diff --git a/lisp/custom.el b/lisp/custom.el index b3311a1783..d21e398646 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -1292,6 +1292,7 @@ custom-available-themes (let ((suffix "-theme\\.el\\'") themes) (dolist (dir (custom-theme--load-path)) + ;; `custom-theme--load-path' promises DIR exists. (dolist (file (directory-files dir nil suffix)) (let ((theme (intern (substring file 0 (string-match-p suffix file))))) (and (custom-theme-name-valid-p theme) @@ -1300,6 +1301,8 @@ custom-available-themes (nreverse themes))) (defun custom-theme--load-path () + "Expand `custom-theme-load-path' into list of directories. +Only existing directories are included in the path returned." (let (lpath) (dolist (f custom-theme-load-path) (cond ((eq f 'custom-theme-directory) [-- Attachment #3: Type: text/plain, Size: 1517 bytes --] >> >> - (define-key map "\C-x\C-s" 'custom-theme-write) >> >> - (define-key map "q" 'Custom-buffer-done) >> >> - (define-key map "n" 'widget-forward) >> >> - (define-key map "p" 'widget-backward) >> >> + (define-key map "\C-x\C-s" #'custom-theme-write) >> >> + (define-key map "q" #'Custom-buffer-done) >> >> + (define-key map "n" #'widget-forward) >> >> + (define-key map "p" #'widget-backward) >> > >> > Really? Are we going to switch to #'foo even in key bindings? >> >> Though I personally prefer to consistently #'-quote function symbols in >> my own code, both for the extra byte-compiler check and narrower >> in-buffer completion, I have no strong opinion here; I was simply making >> the change in a sweeping fashion, in line with what I had perceived as a >> welcome style. Out of curiosity, though, what makes key bindings >> special w.r.t. quoting? > > Stefan gave one reason (with which I agree). From POV, it's another > stab into my heart of a veteran reader of Emacs Lisp code. I recently > find the code harder and harder to read due to all the new syntax and > unfamiliar functions. You can ignore me on that, though. No, it's a respectable point and I appreciate it. Besides, my original intent was to change how themes are loaded, not how their libraries are quoted; I simply got carried away, and I'm sure there's precedent on the latter elsewhere. Let me know whether any heart stabs remain in the last patchset and I'll gladly revert them. Thanks, -- Basil ^ permalink raw reply related [flat|nested] 33+ messages in thread
* Re: Byte-compilation of custom themes 2018-05-11 20:43 ` Basil L. Contovounesios @ 2018-05-12 7:04 ` Eli Zaretskii 2018-06-01 20:48 ` Basil L. Contovounesios 0 siblings, 1 reply; 33+ messages in thread From: Eli Zaretskii @ 2018-05-12 7:04 UTC (permalink / raw To: Basil L. Contovounesios; +Cc: monnier, emacs-devel > From: "Basil L. Contovounesios" <contovob@tcd.ie> > Cc: <monnier@IRO.UMontreal.CA>, <emacs-devel@gnu.org> > Date: Fri, 11 May 2018 21:43:42 +0100 > > > We should at least have a comment there that we are relying on > > custom-theme--load-path to do the test, and perhaps also an assertion. > > Do you mean a cl-assertion, or an emulation thereof? I meant cl-assert. > Either way, what is the benefit of barfing before directory-files does? That you can control the text of the error message, and make it more user-friendly. Also, an assertion clearly means we intended this not to happen, rather than that the code failed to handle some valid situation. Once again, the minimum I requested was a comment; it's up to you whether to use cl-assert. But see below. > Wouldn't a docstring for custom-theme--load-path and a comment in > custom-available-themes suffice for the reader (they do for me)? We've seen many situations where code guidelines are violated, for whatever reasons, so just documenting stuff is not enough. Moreover, custom-theme--load-path might some day change and invalidate our assumption. The way to prevent that from happening could be either having the assertion in the caller, or by adding a test to the test suite that makes sure the list returned by custom-theme--load-path never includes anything but existing directories. > (dolist (dir (custom-theme--load-path)) > + ;; `custom-theme--load-path' promises DIR exists. "promises DIR exists and is a directory", I think. > (defun custom-theme--load-path () > + "Expand `custom-theme-load-path' into list of directories. > +Only existing directories are included in the path returned." I'd find this text a bit of a riddle. How about this instead: "Expand `custom-theme-load-path' into list of directories. Members of `custom-theme-load-path' that either don't exist or are not directories are omitted from the expansion." Thanks. ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Byte-compilation of custom themes 2018-05-12 7:04 ` Eli Zaretskii @ 2018-06-01 20:48 ` Basil L. Contovounesios 2018-06-01 21:07 ` Basil L. Contovounesios 2018-06-02 11:24 ` Eli Zaretskii 0 siblings, 2 replies; 33+ messages in thread From: Basil L. Contovounesios @ 2018-06-01 20:48 UTC (permalink / raw To: Eli Zaretskii; +Cc: monnier, emacs-devel [-- Attachment #1: Type: text/plain, Size: 3464 bytes --] I realise this is low priority stuff, but I'm nonetheless sorry for taking so long to respond. Eli Zaretskii <eliz@gnu.org> writes: >> From: "Basil L. Contovounesios" <contovob@tcd.ie> >> Cc: <monnier@IRO.UMontreal.CA>, <emacs-devel@gnu.org> >> Date: Fri, 11 May 2018 21:43:42 +0100 >> >> > We should at least have a comment there that we are relying on >> > custom-theme--load-path to do the test, and perhaps also an assertion. >> >> Do you mean a cl-assertion, or an emulation thereof? > > I meant cl-assert. Unless I (being unfamiliar with the subtleties of the build and bootstrap process) am missing something, I think it's too early to load cl-lib here; at least 'make bootstrap' fails for me when I add (eval-when-compile (require 'cl-lib)) to custom.el. Is there a way around this? Is the (unless DIRP (signal 'file-missing ...)) spiel from my last email a suitable alternative? Would doing that be overkill? >> Either way, what is the benefit of barfing before directory-files does? > > That you can control the text of the error message, and make it more > user-friendly. Also, an assertion clearly means we intended this not > to happen, rather than that the code failed to handle some valid > situation. Understood. I've noticed, however, that many, if not most, uses of cl-assert don't specify a custom error message. For future reference, is this acceptable practice, or would we rather see consistent use of more informative messages? > Once again, the minimum I requested was a comment; it's up to you > whether to use cl-assert. But see below. > >> Wouldn't a docstring for custom-theme--load-path and a comment in >> custom-available-themes suffice for the reader (they do for me)? > > We've seen many situations where code guidelines are violated, for > whatever reasons, so just documenting stuff is not enough. Moreover, > custom-theme--load-path might some day change and invalidate our > assumption. The way to prevent that from happening could be either > having the assertion in the caller, or by adding a test to the test > suite that makes sure the list returned by custom-theme--load-path > never includes anything but existing directories. A limitation (which does not apply in this case) of having the assertion in the caller is that this doesn't necessarily cover future callers, and even if it does, then there are multiple callers checking the same thing. Either way, I think adding a regression test is a good idea. >> (dolist (dir (custom-theme--load-path)) >> + ;; `custom-theme--load-path' promises DIR exists. > > "promises DIR exists and is a directory", I think. Right, I was being lazy and imprecise by relying on the name DIR to convey its being a directory. >> (defun custom-theme--load-path () >> + "Expand `custom-theme-load-path' into list of directories. >> +Only existing directories are included in the path returned." > > I'd find this text a bit of a riddle. How about this instead: > > "Expand `custom-theme-load-path' into list of directories. > Members of `custom-theme-load-path' that either don't exist or are not > directories are omitted from the expansion." SGTM, thanks. I reattach the eight patches, updated for the feedback above. The third patch has been updated to include the aforementioned custom-theme-load-path documentation and tests. The eighth patch now touches two more subr-x.el functions and adds tests for its changes. Thanks, -- Basil [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: 0001-Improve-loading-of-byte-compiled-custom-themes.patch --] [-- Type: text/x-diff, Size: 4290 bytes --] From d4a711a775649c50e36e4bdc244c79f51ae7a7bc Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Wed, 9 May 2018 22:20:47 +0100 Subject: [PATCH 1/8] Improve loading of byte-compiled custom themes * lisp/custom.el (load-theme): Load byte-compiled file of safe themes when available. https://lists.gnu.org/archive/html/emacs-devel/2018-01/msg00614.html https://lists.gnu.org/archive/html/emacs-devel/2018-02/msg00060.html --- lisp/custom.el | 78 ++++++++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 37 deletions(-) diff --git a/lisp/custom.el b/lisp/custom.el index b7539685a8..1fed5dce53 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -1221,43 +1221,47 @@ load-theme (put theme 'theme-settings nil) (put theme 'theme-feature nil) (put theme 'theme-documentation nil)) - (let ((fn (locate-file (concat (symbol-name theme) "-theme.el") - (custom-theme--load-path) - '("" "c")))) - (unless fn - (error "Unable to find theme file for `%s'" theme)) - (with-temp-buffer - (insert-file-contents fn) - ;; Check file safety with `custom-safe-themes', prompting the - ;; user if necessary. - (when (or no-confirm - (eq custom-safe-themes t) - (and (memq 'default custom-safe-themes) - (equal (file-name-directory fn) - (expand-file-name "themes/" data-directory))) - (let ((hash (secure-hash 'sha256 (current-buffer)))) - (or (member hash custom-safe-themes) - (custom-theme-load-confirm hash)))) - (let ((custom--inhibit-theme-enable t) - (buffer-file-name fn)) ;For load-history. - (eval-buffer)) - ;; Optimization: if the theme changes the `default' face, put that - ;; entry first. This avoids some `frame-set-background-mode' rigmarole - ;; by assigning the new background immediately. - (let* ((settings (get theme 'theme-settings)) - (tail settings) - found) - (while (and tail (not found)) - (and (eq (nth 0 (car tail)) 'theme-face) - (eq (nth 1 (car tail)) 'default) - (setq found (car tail))) - (setq tail (cdr tail))) - (if found - (put theme 'theme-settings (cons found (delq found settings))))) - ;; Finally, enable the theme. - (unless no-enable - (enable-theme theme)) - t)))) + (let ((file (locate-file (concat (symbol-name theme) "-theme.el") + (custom-theme--load-path) + '("" "c"))) + (custom--inhibit-theme-enable t)) + ;; Check file safety with `custom-safe-themes', prompting the + ;; user if necessary. + (cond ((not file) + (error "Unable to find theme file for `%s'" theme)) + ((or no-confirm + (eq custom-safe-themes t) + (and (memq 'default custom-safe-themes) + (equal (file-name-directory file) + (expand-file-name "themes/" data-directory)))) + ;; Theme is safe; load byte-compiled version if available. + (load (file-name-sans-extension file) nil t nil t)) + ((with-temp-buffer + (insert-file-contents file) + (let ((hash (secure-hash 'sha256 (current-buffer)))) + (when (or (member hash custom-safe-themes) + (custom-theme-load-confirm hash)) + (eval-buffer nil nil file) + t)))) + (t + (error "Unable to load theme `%s'" theme)))) + ;; Optimization: if the theme changes the `default' face, put that + ;; entry first. This avoids some `frame-set-background-mode' rigmarole + ;; by assigning the new background immediately. + (let* ((settings (get theme 'theme-settings)) + (tail settings) + found) + (while (and tail (not found)) + (and (eq (nth 0 (car tail)) 'theme-face) + (eq (nth 1 (car tail)) 'default) + (setq found (car tail))) + (setq tail (cdr tail))) + (when found + (put theme 'theme-settings (cons found (delq found settings))))) + ;; Finally, enable the theme. + (unless no-enable + (enable-theme theme)) + t) (defun custom-theme-load-confirm (hash) "Query the user about loading a Custom theme that may not be safe. -- 2.17.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #3: 0002-Disable-no-byte-compile-in-built-in-themes.patch --] [-- Type: text/x-diff, Size: 6291 bytes --] From f625cbdc4dbbcfa59a5773f193e4048bbb024191 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Wed, 9 May 2018 22:30:48 +0100 Subject: [PATCH 2/8] Disable no-byte-compile in built-in themes * etc/themes/adwaita-theme.el: * etc/themes/deeper-blue-theme.el: * etc/themes/dichromacy-theme.el: * etc/themes/leuven-theme.el: * etc/themes/light-blue-theme.el: * etc/themes/manoj-dark-theme.el: * etc/themes/misterioso-theme.el: * etc/themes/tango-dark-theme.el: * etc/themes/tango-theme.el: * etc/themes/tsdh-dark-theme.el: * etc/themes/tsdh-light-theme.el: * etc/themes/wheatgrass-theme.el: * etc/themes/whiteboard-theme.el: * etc/themes/wombat-theme.el: Disable no-byte-compile. https://lists.gnu.org/archive/html/emacs-devel/2018-01/msg00614.html https://lists.gnu.org/archive/html/emacs-devel/2018-02/msg00060.html --- etc/themes/adwaita-theme.el | 4 ---- etc/themes/deeper-blue-theme.el | 4 ---- etc/themes/dichromacy-theme.el | 4 ---- etc/themes/leuven-theme.el | 1 - etc/themes/light-blue-theme.el | 4 ---- etc/themes/manoj-dark-theme.el | 4 ---- etc/themes/misterioso-theme.el | 4 ---- etc/themes/tango-dark-theme.el | 4 ---- etc/themes/tango-theme.el | 4 ---- etc/themes/tsdh-dark-theme.el | 4 ---- etc/themes/tsdh-light-theme.el | 5 ----- etc/themes/wheatgrass-theme.el | 4 ---- etc/themes/whiteboard-theme.el | 4 ---- etc/themes/wombat-theme.el | 4 ---- 14 files changed, 54 deletions(-) diff --git a/etc/themes/adwaita-theme.el b/etc/themes/adwaita-theme.el index b376153510..415db8a191 100644 --- a/etc/themes/adwaita-theme.el +++ b/etc/themes/adwaita-theme.el @@ -99,8 +99,4 @@ adwaita `(diff-added ((,class (:bold t :foreground "#4E9A06")))) `(diff-removed ((,class (:bold t :foreground "#F5666D")))))) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; adwaita-theme.el ends here diff --git a/etc/themes/deeper-blue-theme.el b/etc/themes/deeper-blue-theme.el index c6aa1751f4..0700f4f23d 100644 --- a/etc/themes/deeper-blue-theme.el +++ b/etc/themes/deeper-blue-theme.el @@ -110,8 +110,4 @@ deeper-blue (provide-theme 'deeper-blue) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; deeper-blue-theme.el ends here diff --git a/etc/themes/dichromacy-theme.el b/etc/themes/dichromacy-theme.el index 793209c055..bfced43aee 100644 --- a/etc/themes/dichromacy-theme.el +++ b/etc/themes/dichromacy-theme.el @@ -122,8 +122,4 @@ dichromacy (provide-theme 'dichromacy) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; dichromacy-theme.el ends here diff --git a/etc/themes/leuven-theme.el b/etc/themes/leuven-theme.el index 5c0d19ce81..c3c666588b 100644 --- a/etc/themes/leuven-theme.el +++ b/etc/themes/leuven-theme.el @@ -708,7 +708,6 @@ leuven ;; time-stamp-format: "%:y%02m%02d.%02H%02M" ;; time-stamp-start: "Version: " ;; time-stamp-end: "$" -;; no-byte-compile: t ;; End: ;;; leuven-theme.el ends here diff --git a/etc/themes/light-blue-theme.el b/etc/themes/light-blue-theme.el index 9935c565fb..ba00db6a49 100644 --- a/etc/themes/light-blue-theme.el +++ b/etc/themes/light-blue-theme.el @@ -61,8 +61,4 @@ light-blue (provide-theme 'light-blue) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; light-blue-theme.el ends here diff --git a/etc/themes/manoj-dark-theme.el b/etc/themes/manoj-dark-theme.el index fe61441d78..ddcaa0bd99 100644 --- a/etc/themes/manoj-dark-theme.el +++ b/etc/themes/manoj-dark-theme.el @@ -700,8 +700,4 @@ manoj-dark (provide-theme 'manoj-dark) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; manoj-dark.el ends here diff --git a/etc/themes/misterioso-theme.el b/etc/themes/misterioso-theme.el index 42e448d28b..6c1eec0f42 100644 --- a/etc/themes/misterioso-theme.el +++ b/etc/themes/misterioso-theme.el @@ -103,8 +103,4 @@ misterioso (provide-theme 'misterioso) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; misterioso-theme.el ends here diff --git a/etc/themes/tango-dark-theme.el b/etc/themes/tango-dark-theme.el index 3b6eeb702e..dae77a5e62 100644 --- a/etc/themes/tango-dark-theme.el +++ b/etc/themes/tango-dark-theme.el @@ -170,8 +170,4 @@ tango-dark (provide-theme 'tango-dark) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; tango-dark-theme.el ends here diff --git a/etc/themes/tango-theme.el b/etc/themes/tango-theme.el index a7a79c04ad..4fe2480bc7 100644 --- a/etc/themes/tango-theme.el +++ b/etc/themes/tango-theme.el @@ -154,8 +154,4 @@ tango (provide-theme 'tango) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; tango-theme.el ends here diff --git a/etc/themes/tsdh-dark-theme.el b/etc/themes/tsdh-dark-theme.el index 287fef8253..c216750cb2 100644 --- a/etc/themes/tsdh-dark-theme.el +++ b/etc/themes/tsdh-dark-theme.el @@ -144,8 +144,4 @@ tsdh-dark (provide-theme 'tsdh-dark) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; tsdh-dark-theme.el ends here diff --git a/etc/themes/tsdh-light-theme.el b/etc/themes/tsdh-light-theme.el index 17a86fdbfe..ce9d1a2c3c 100644 --- a/etc/themes/tsdh-light-theme.el +++ b/etc/themes/tsdh-light-theme.el @@ -106,9 +106,4 @@ tsdh-light (provide-theme 'tsdh-light) - -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; tsdh-light-theme.el ends here diff --git a/etc/themes/wheatgrass-theme.el b/etc/themes/wheatgrass-theme.el index 9585e3aa6e..8d34c28bf4 100644 --- a/etc/themes/wheatgrass-theme.el +++ b/etc/themes/wheatgrass-theme.el @@ -83,8 +83,4 @@ wheatgrass (provide-theme 'wheatgrass) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; wheatgrass-theme.el ends here diff --git a/etc/themes/whiteboard-theme.el b/etc/themes/whiteboard-theme.el index 5db0ddd68d..fe46cb0928 100644 --- a/etc/themes/whiteboard-theme.el +++ b/etc/themes/whiteboard-theme.el @@ -100,8 +100,4 @@ whiteboard (provide-theme 'whiteboard) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; whiteboard-theme.el ends here diff --git a/etc/themes/wombat-theme.el b/etc/themes/wombat-theme.el index 583b8dc3f6..00f29bb9fa 100644 --- a/etc/themes/wombat-theme.el +++ b/etc/themes/wombat-theme.el @@ -102,8 +102,4 @@ wombat (provide-theme 'wombat) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; wombat-theme.el ends here -- 2.17.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #4: 0003-Fix-custom-available-themes-file-expansion.patch --] [-- Type: text/x-diff, Size: 6515 bytes --] From 5368d8697d49ae8fb493031be22dee2dbe76624c Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Wed, 2 May 2018 21:18:24 +0100 Subject: [PATCH 3/8] Fix custom-available-themes file expansion For discussion, see thread starting at https://lists.gnu.org/archive/html/emacs-devel/2018-05/msg00222.html. * lisp/custom.el: (custom-available-themes): Use directory-files instead of performing arbitrary wildcard expansion in filenames. (custom-theme--load-path): Document return value. * test/lisp/custom-tests.el: New file. (custom-theme--load-path): New test. --- lisp/custom.el | 22 +++++----- test/lisp/custom-tests.el | 87 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+), 10 deletions(-) create mode 100644 test/lisp/custom-tests.el diff --git a/lisp/custom.el b/lisp/custom.el index 1fed5dce53..157bb318e3 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -1299,19 +1299,21 @@ custom-available-themes loaded, and no effort is made to check that the files contain valid Custom themes. For a list of loaded themes, check the variable `custom-known-themes'." - (let (sym themes) + (let ((suffix "-theme\\.el\\'") + themes) (dolist (dir (custom-theme--load-path)) - (when (file-directory-p dir) - (dolist (file (file-expand-wildcards - (expand-file-name "*-theme.el" dir) t)) - (setq file (file-name-nondirectory file)) - (and (string-match "\\`\\(.+\\)-theme.el\\'" file) - (setq sym (intern (match-string 1 file))) - (custom-theme-name-valid-p sym) - (push sym themes))))) - (nreverse (delete-dups themes)))) + ;; `custom-theme--load-path' promises DIR exists and is a directory. + (dolist (file (directory-files dir nil suffix)) + (let ((theme (intern (substring file 0 (string-match-p suffix file))))) + (and (custom-theme-name-valid-p theme) + (not (memq theme themes)) + (push theme themes))))) + (nreverse themes))) (defun custom-theme--load-path () + "Expand `custom-theme-load-path' into a list of directories. +Members of `custom-theme-load-path' that either don't exist or +are not directories are omitted from the expansion." (let (lpath) (dolist (f custom-theme-load-path) (cond ((eq f 'custom-theme-directory) diff --git a/test/lisp/custom-tests.el b/test/lisp/custom-tests.el new file mode 100644 index 0000000000..96887f8f5f --- /dev/null +++ b/test/lisp/custom-tests.el @@ -0,0 +1,87 @@ +;;; custom-tests.el --- tests for custom.el -*- lexical-binding: t -*- + +;; Copyright (C) 2018 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs 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. + +;; GNU Emacs 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 program. If not, see <https://www.gnu.org/licenses/>. + +;;; Code: + +(require 'ert) + +(ert-deftest custom-theme--load-path () + "Test `custom-theme--load-path' behavior." + (let ((tmpdir (file-name-as-directory (make-temp-file "custom-tests-" t)))) + (unwind-protect + ;; Create all temporary files under the same deletable parent. + (let ((temporary-file-directory tmpdir)) + ;; Path is empty. + (let ((custom-theme-load-path ())) + (should (null (custom-theme--load-path)))) + + ;; Path comprises non-existent file. + (let* ((name (make-temp-name tmpdir)) + (custom-theme-load-path (list name))) + (should (not (file-exists-p name))) + (should (null (custom-theme--load-path)))) + + ;; Path comprises existing file. + (let* ((file (make-temp-file "file")) + (custom-theme-load-path (list file))) + (should (file-exists-p file)) + (should (not (file-directory-p file))) + (should (null (custom-theme--load-path)))) + + ;; Path comprises existing directory. + (let* ((dir (make-temp-file "dir" t)) + (custom-theme-load-path (list dir))) + (should (file-directory-p dir)) + (should (equal (custom-theme--load-path) custom-theme-load-path))) + + ;; Expand `custom-theme-directory' path element. + (let ((custom-theme-load-path '(custom-theme-directory))) + (let ((custom-theme-directory (make-temp-name tmpdir))) + (should (not (file-exists-p custom-theme-directory))) + (should (null (custom-theme--load-path)))) + (let ((custom-theme-directory (make-temp-file "file"))) + (should (file-exists-p custom-theme-directory)) + (should (not (file-directory-p custom-theme-directory))) + (should (null (custom-theme--load-path)))) + (let ((custom-theme-directory (make-temp-file "dir" t))) + (should (file-directory-p custom-theme-directory)) + (should (equal (custom-theme--load-path) + (list custom-theme-directory))))) + + ;; Expand t path element. + (let ((custom-theme-load-path '(t))) + (let ((data-directory (make-temp-name tmpdir))) + (should (not (file-exists-p data-directory))) + (should (null (custom-theme--load-path)))) + (let ((data-directory tmpdir) + (themedir (expand-file-name "themes" tmpdir))) + (should (not (file-exists-p themedir))) + (should (null (custom-theme--load-path))) + (with-temp-file themedir) + (should (file-exists-p themedir)) + (should (not (file-directory-p themedir))) + (should (null (custom-theme--load-path))) + (delete-file themedir) + (make-directory themedir) + (should (file-directory-p themedir)) + (should (equal (custom-theme--load-path) (list themedir)))))) + (when (file-directory-p tmpdir) + (delete-directory tmpdir t))))) + +;;; custom-tests.el ends here -- 2.17.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #5: 0004-lisp-custom.el-Use-lexical-binding.patch --] [-- Type: text/x-diff, Size: 7797 bytes --] From bc839204dfa54de338f33f2814a144fd91ac20ef Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Fri, 11 May 2018 16:09:57 +0100 Subject: [PATCH 4/8] * lisp/custom.el: Use lexical-binding Remove duplicate 'Custom Themes' comment heading. (deftheme, custom-declare-theme): Fix advertised calling convention. (custom-enabled-themes): Fix message grammar. --- lisp/custom.el | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/lisp/custom.el b/lisp/custom.el index 157bb318e3..7ca71dd895 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -1,4 +1,4 @@ -;;; custom.el --- tools for declaring and initializing options +;;; custom.el --- tools for declaring and initializing options -*- lexical-binding: t -*- ;; ;; Copyright (C) 1996-1997, 1999, 2001-2018 Free Software Foundation, ;; Inc. @@ -150,7 +150,7 @@ custom-declare-variable (put symbol 'force-value nil)) (if (keywordp doc) (error "Doc string is missing")) - (let ((initialize 'custom-initialize-reset) + (let ((initialize #'custom-initialize-reset) (requests nil)) (unless (memq :group args) (custom-add-to-group (custom-current-group) symbol 'custom-variable)) @@ -426,7 +426,7 @@ custom-current-group (defun custom-declare-group (symbol members doc &rest args) "Like `defgroup', but SYMBOL is evaluated as a normal argument." (while members - (apply 'custom-add-to-group symbol (car members)) + (apply #'custom-add-to-group symbol (car members)) (setq members (cdr members))) (when doc ;; This text doesn't get into DOC. @@ -618,11 +618,8 @@ custom-note-var-changed The result is that the change is treated as having been made through Custom." (put variable 'customized-value (list (custom-quote (eval variable))))) -\f -;;; Custom Themes - -;;; Loading files needed to customize a symbol. -;;; This is in custom.el because menu-bar.el needs it for toggle cmds. +;; Loading files needed to customize a symbol. +;; This is in custom.el because menu-bar.el needs it for toggle cmds. (defvar custom-load-recursion nil "Hack to avoid recursive dependencies.") @@ -715,7 +712,7 @@ customize-mark-to-save Return non-nil if the `saved-value' property actually changed." (custom-load-symbol symbol) - (let* ((get (or (get symbol 'custom-get) 'default-value)) + (let* ((get (or (get symbol 'custom-get) #'default-value)) (value (funcall get symbol)) (saved (get symbol 'saved-value)) (standard (get symbol 'standard-value)) @@ -744,7 +741,7 @@ customize-mark-as-set Return non-nil if the `customized-value' property actually changed." (custom-load-symbol symbol) - (let* ((get (or (get symbol 'custom-get) 'default-value)) + (let* ((get (or (get symbol 'custom-get) #'default-value)) (value (funcall get symbol)) (customized (get symbol 'customized-value)) (old (or (get symbol 'saved-value) (get symbol 'standard-value)))) @@ -776,7 +773,7 @@ custom-reevaluate-setting ;; always do the funcall step, even if symbol was not bound before. (or (default-boundp symbol) (eval `(defvar ,symbol nil))) ; reset below, so any value is fine - (funcall (or (get symbol 'custom-set) 'set-default) + (funcall (or (get symbol 'custom-set) #'set-default) symbol (eval (car (or (get symbol 'saved-value) (get symbol 'standard-value)))))) @@ -941,7 +938,7 @@ custom-set-variables REQUEST is a list of features we must require in order to handle SYMBOL properly. COMMENT is a comment string about SYMBOL." - (apply 'custom-theme-set-variables 'user args)) + (apply #'custom-theme-set-variables 'user args)) (defun custom-theme-set-variables (theme &rest args) "Initialize variables for theme THEME according to settings in ARGS. @@ -989,8 +986,8 @@ custom-theme-set-variables set) (when requests (put symbol 'custom-requests requests) - (mapc 'require requests)) - (setq set (or (get symbol 'custom-set) 'custom-set-default)) + (mapc #'require requests)) + (setq set (or (get symbol 'custom-set) #'custom-set-default)) (put symbol 'saved-value (list value)) (put symbol 'saved-variable-comment comment) ;; Allow for errors in the case where the setter has @@ -1086,26 +1083,29 @@ custom--sort-vars-1 ;; they were used to supply keyword-value pairs like `:immediate', ;; `:variable-reset-string', etc. We don't use any of these, so ignore them. -(defmacro deftheme (theme &optional doc &rest ignored) +(defmacro deftheme (theme &optional doc &rest _ignored) "Declare THEME to be a Custom theme. The optional argument DOC is a doc string describing the theme. Any theme `foo' should be defined in a file called `foo-theme.el'; see `custom-make-theme-feature' for more information." - (declare (doc-string 2)) + (declare (doc-string 2) + (advertised-calling-convention (theme &optional doc) "22.1")) (let ((feature (custom-make-theme-feature theme))) ;; It is better not to use backquote in this file, ;; because that makes a bootstrapping problem ;; if you need to recompile all the Lisp files using interpreted code. (list 'custom-declare-theme (list 'quote theme) (list 'quote feature) doc))) -(defun custom-declare-theme (theme feature &optional doc &rest ignored) +(defun custom-declare-theme (theme feature &optional doc &rest _ignored) "Like `deftheme', but THEME is evaluated as a normal argument. FEATURE is the feature this theme provides. Normally, this is a symbol created from THEME by `custom-make-theme-feature'." + (declare (advertised-calling-convention (theme feature &optional doc) "22.1")) (unless (custom-theme-name-valid-p theme) (error "Custom theme cannot be named %S" theme)) - (add-to-list 'custom-known-themes theme) + (unless (memq theme custom-known-themes) + (push theme custom-known-themes)) (put theme 'theme-feature feature) (when doc (put theme 'theme-documentation doc))) @@ -1206,7 +1206,7 @@ load-theme (interactive (list (intern (completing-read "Load custom theme: " - (mapcar 'symbol-name + (mapcar #'symbol-name (custom-available-themes)))) nil nil)) (unless (custom-theme-name-valid-p theme) @@ -1391,9 +1391,9 @@ custom-enabled-themes themes (delq theme themes))))) (enable-theme 'user) (custom-set-default symbol themes) - (if failures - (message "Failed to enable theme: %s" - (mapconcat 'symbol-name failures ", ")))))) + (when failures + (message "Failed to enable theme(s): %s" + (mapconcat #'symbol-name failures ", ")))))) (defsubst custom-theme-enabled-p (theme) "Return non-nil if THEME is enabled." @@ -1405,7 +1405,7 @@ disable-theme (interactive (list (intern (completing-read "Disable custom theme: " - (mapcar 'symbol-name custom-enabled-themes) + (mapcar #'symbol-name custom-enabled-themes) nil t)))) (when (custom-theme-enabled-p theme) (let ((settings (get theme 'theme-settings))) @@ -1471,7 +1471,7 @@ custom-theme-recalc-variable (if (and valspec (or (get variable 'force-value) (default-boundp variable))) - (funcall (or (get variable 'custom-set) 'set-default) variable + (funcall (or (get variable 'custom-set) #'set-default) variable (eval (car valspec)))))) (defun custom-theme-recalc-face (face) @@ -1512,7 +1512,7 @@ custom-reset-variables (VARIABLE IGNORED) This means reset VARIABLE. (The argument IGNORED is ignored)." - (apply 'custom-theme-reset-variables 'user args)) + (apply #'custom-theme-reset-variables 'user args)) ;;; The End. -- 2.17.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #6: 0005-lisp-cus-theme.el-Use-lexical-binding.patch --] [-- Type: text/x-diff, Size: 5907 bytes --] From d850fa0df54be25d31b69273722754c3f27e28e5 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Fri, 11 May 2018 15:35:09 +0100 Subject: [PATCH 5/8] * lisp/cus-theme.el: Use lexical-binding --- lisp/cus-theme.el | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/lisp/cus-theme.el b/lisp/cus-theme.el index e5e787771b..53389956ad 100644 --- a/lisp/cus-theme.el +++ b/lisp/cus-theme.el @@ -1,4 +1,4 @@ -;;; cus-theme.el -- custom theme creation user interface +;;; cus-theme.el -- custom theme creation user interface -*- lexical-binding: t -*- ;; ;; Copyright (C) 2001-2018 Free Software Foundation, Inc. ;; @@ -47,7 +47,7 @@ custom-new-theme-mode Do not call this mode function yourself. It is meant for internal use." (use-local-map custom-new-theme-mode-map) (custom--initialize-widget-variables) - (set (make-local-variable 'revert-buffer-function) 'custom-theme-revert)) + (set (make-local-variable 'revert-buffer-function) #'custom-theme-revert)) (put 'custom-new-theme-mode 'mode-class 'special) (defvar custom-theme-name nil) @@ -118,13 +118,13 @@ customize-create-theme :tag " Visit Theme " :help-echo "Insert the settings of a pre-defined theme." :action (lambda (_widget &optional _event) - (call-interactively 'custom-theme-visit-theme))) + (call-interactively #'custom-theme-visit-theme))) (widget-insert " ") (widget-create 'push-button :tag " Merge Theme " :help-echo "Merge in the settings of a pre-defined theme." :action (lambda (_widget &optional _event) - (call-interactively 'custom-theme-merge-theme))) + (call-interactively #'custom-theme-merge-theme))) (widget-insert " ") (widget-create 'push-button :tag " Revert " @@ -142,7 +142,7 @@ customize-create-theme (widget-create 'text :value (format-time-string "Created %Y-%m-%d."))) (widget-create 'push-button - :notify (function custom-theme-write) + :notify #'custom-theme-write " Save Theme ") (when (eq theme 'user) (setq custom-theme--migrate-settings t) @@ -188,7 +188,7 @@ customize-create-theme :mouse-face 'highlight :pressed-face 'highlight :action (lambda (_widget &optional _event) - (call-interactively 'custom-theme-add-face))) + (call-interactively #'custom-theme-add-face))) ;; If THEME is non-nil, insert all of that theme's variables. (widget-insert "\n\n Theme variables:\n ") @@ -207,7 +207,7 @@ customize-create-theme :mouse-face 'highlight :pressed-face 'highlight :action (lambda (_widget &optional _event) - (call-interactively 'custom-theme-add-variable))) + (call-interactively #'custom-theme-add-variable))) (widget-insert ?\n) (widget-setup) (goto-char (point-min)) @@ -254,7 +254,7 @@ custom-theme-add-var-1 :tag (custom-unlispify-tag-name symbol) :value symbol :shown-value (list val) - :notify 'ignore + :notify #'ignore :custom-level 0 :custom-state 'hidden :custom-style 'simple)) @@ -313,7 +313,7 @@ custom-theme-visit-theme (interactive (list (intern (completing-read "Find custom theme: " - (mapcar 'symbol-name + (mapcar #'symbol-name (custom-available-themes)))))) (unless (custom-theme-name-valid-p theme) (error "No valid theme named `%s'" theme)) @@ -328,7 +328,7 @@ custom-theme-merge-theme (interactive (list (intern (completing-read "Merge custom theme: " - (mapcar 'symbol-name + (mapcar #'symbol-name (custom-available-themes)))))) (unless (eq theme 'user) (unless (custom-theme-name-valid-p theme) @@ -343,8 +343,8 @@ custom-theme-merge-theme (memq name '(custom-enabled-themes custom-safe-themes))) (funcall (if option - 'custom-theme-add-variable - 'custom-theme-add-face) + #'custom-theme-add-variable + #'custom-theme-add-face) name value))))) theme) @@ -475,7 +475,7 @@ describe-theme (interactive (list (intern (completing-read "Describe custom theme: " - (mapcar 'symbol-name + (mapcar #'symbol-name (custom-available-themes)))))) (unless (custom-theme-name-valid-p theme) (error "Invalid theme name `%s'" theme)) @@ -616,11 +616,11 @@ customize-themes (widget-create 'push-button :tag " Save Theme Settings " :help-echo "Save the selected themes for future sessions." - :action 'custom-theme-save) + :action #'custom-theme-save) (widget-insert ?\n) (widget-create 'checkbox :value custom-theme-allow-multiple-selections - :action 'custom-theme-selections-toggle) + :action #'custom-theme-selections-toggle) (widget-insert (propertize " Select more than one theme at a time" 'face '(variable-pitch (:height 0.9)))) @@ -632,13 +632,13 @@ customize-themes :value (custom-theme-enabled-p theme) :theme-name theme :help-echo help-echo - :action 'custom-theme-checkbox-toggle)) + :action #'custom-theme-checkbox-toggle)) (push (cons theme widget) custom--listed-themes) (widget-create-child-and-convert widget 'push-button :button-face-get 'ignore :mouse-face-get 'ignore :value (format " %s" theme) - :action 'widget-parent-action + :action #'widget-parent-action :help-echo help-echo) (widget-insert " -- " (propertize (custom-theme-summary theme) -- 2.17.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #7: 0006-Minor-custom.el-simplifications.patch --] [-- Type: text/x-diff, Size: 7892 bytes --] From 531b5169240c4f7a39a3eabfec78154789d48fdc Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Thu, 31 May 2018 18:37:02 +0100 Subject: [PATCH 6/8] Minor custom.el simplifications * lisp/custom.el (custom-quote): Duplicate macroexp-quote. (custom-load-symbol, customize-mark-to-save, customize-mark-as-set) (custom-theme-name-valid-p, enable-theme, custom-enabled-themes) (disable-theme): Simplify logic. --- lisp/custom.el | 103 ++++++++++++++++++++++--------------------------- 1 file changed, 46 insertions(+), 57 deletions(-) diff --git a/lisp/custom.el b/lisp/custom.el index 7ca71dd895..076790b661 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -630,14 +630,12 @@ custom-load-symbol (let ((custom-load-recursion t)) ;; Load these files if not already done, ;; to make sure we know all the dependencies of SYMBOL. - (condition-case nil - (require 'cus-load) - (error nil)) - (condition-case nil - (require 'cus-start) - (error nil)) + (ignore-errors + (require 'cus-load)) + (ignore-errors + (require 'cus-start)) (dolist (load (get symbol 'custom-loads)) - (cond ((symbolp load) (condition-case nil (require load) (error nil))) + (cond ((symbolp load) (ignore-errors (require load))) ;; This is subsumed by the test below, but it's much faster. ((assoc load load-history)) ;; This was just (assoc (locate-library load) load-history) @@ -655,7 +653,7 @@ custom-load-symbol ;; We are still loading it when we call this, ;; and it is not in load-history yet. ((equal load "cus-edit")) - (t (condition-case nil (load load) (error nil)))))))) + (t (ignore-errors (load load)))))))) \f (defvar custom-local-buffer nil "Non-nil, in a Customization buffer, means customize a specific buffer. @@ -688,16 +686,12 @@ custom-set-minor-mode (defun custom-quote (sexp) "Quote SEXP if it is not self quoting." - (if (or (memq sexp '(t nil)) - (keywordp sexp) - (and (listp sexp) - (memq (car sexp) '(lambda))) - (stringp sexp) - (numberp sexp) - (vectorp sexp) -;;; (and (fboundp 'characterp) -;;; (characterp sexp)) - ) + ;; Can't use `macroexp-quote' because it is loaded after `custom.el' + ;; during bootstrap. See `loadup.el'. + (if (and (not (consp sexp)) + (or (keywordp sexp) + (not (symbolp sexp)) + (booleanp sexp))) sexp (list 'quote sexp))) @@ -718,12 +712,10 @@ customize-mark-to-save (standard (get symbol 'standard-value)) (comment (get symbol 'customized-variable-comment))) ;; Save default value if different from standard value. - (if (or (null standard) - (not (equal value (condition-case nil - (eval (car standard)) - (error nil))))) - (put symbol 'saved-value (list (custom-quote value))) - (put symbol 'saved-value nil)) + (put symbol 'saved-value + (unless (and standard + (equal value (ignore-errors (eval (car standard))))) + (list (custom-quote value)))) ;; Clear customized information (set, but not saved). (put symbol 'customized-value nil) ;; Save any comment that might have been set. @@ -747,9 +739,8 @@ customize-mark-as-set (old (or (get symbol 'saved-value) (get symbol 'standard-value)))) ;; Mark default value as set if different from old value. (if (not (and old - (equal value (condition-case nil - (eval (car old)) - (error nil))))) + (equal value (ignore-errors + (eval (car old)))))) (progn (put symbol 'customized-value (list (custom-quote value))) (custom-push-theme 'theme-value symbol 'user 'set (custom-quote value))) @@ -1284,11 +1275,9 @@ custom-theme-load-confirm (defun custom-theme-name-valid-p (name) "Return t if NAME is a valid name for a Custom theme, nil otherwise. NAME should be a symbol." - (and (symbolp name) - name - (not (or (zerop (length (symbol-name name))) - (eq name 'user) - (eq name 'changed))))) + (and (not (memq name '(nil user changed))) + (symbolp name) + (not (string= "" (symbol-name name))))) (defun custom-available-themes () "Return a list of Custom themes available for loading. @@ -1336,8 +1325,8 @@ enable-theme (completing-read "Enable custom theme: " obarray (lambda (sym) (get sym 'theme-settings)) t)))) - (if (not (custom-theme-p theme)) - (error "Undefined Custom theme %s" theme)) + (unless (custom-theme-p theme) + (error "Undefined Custom theme %s" theme)) (let ((settings (get theme 'theme-settings))) ;; Loop through theme settings, recalculating vars/faces. (dolist (s settings) @@ -1377,18 +1366,18 @@ custom-enabled-themes (let (failures) (setq themes (delq 'user (delete-dups themes))) ;; Disable all themes not in THEMES. - (if (boundp symbol) - (dolist (theme (symbol-value symbol)) - (if (not (memq theme themes)) - (disable-theme theme)))) + (dolist (theme (and (boundp symbol) + (symbol-value symbol))) + (unless (memq theme themes) + (disable-theme theme))) ;; Call `enable-theme' or `load-theme' on each of THEMES. (dolist (theme (reverse themes)) (condition-case nil (if (custom-theme-p theme) (enable-theme theme) (load-theme theme)) - (error (setq failures (cons theme failures) - themes (delq theme themes))))) + (error (push theme failures) + (setq themes (delq theme themes))))) (enable-theme 'user) (custom-set-default symbol themes) (when failures @@ -1421,23 +1410,23 @@ disable-theme ;; If the face spec specified by this theme is in the ;; saved-face property, reset that property. (when (equal (nth 3 s) (get symbol 'saved-face)) - (put symbol 'saved-face (and val (cadr (car val))))))))) - ;; Recompute faces on all frames. - (dolist (frame (frame-list)) - ;; We must reset the fg and bg color frame parameters, or - ;; `face-set-after-frame-default' will use the existing - ;; parameters, which could be from the disabled theme. - (set-frame-parameter frame 'background-color - (custom--frame-color-default - frame :background "background" "Background" - "unspecified-bg" "white")) - (set-frame-parameter frame 'foreground-color - (custom--frame-color-default - frame :foreground "foreground" "Foreground" - "unspecified-fg" "black")) - (face-set-after-frame-default frame)) - (setq custom-enabled-themes - (delq theme custom-enabled-themes))))) + (put symbol 'saved-face (cadar val)))))))) + ;; Recompute faces on all frames. + (dolist (frame (frame-list)) + ;; We must reset the fg and bg color frame parameters, or + ;; `face-set-after-frame-default' will use the existing + ;; parameters, which could be from the disabled theme. + (set-frame-parameter frame 'background-color + (custom--frame-color-default + frame :background "background" "Background" + "unspecified-bg" "white")) + (set-frame-parameter frame 'foreground-color + (custom--frame-color-default + frame :foreground "foreground" "Foreground" + "unspecified-fg" "black")) + (face-set-after-frame-default frame)) + (setq custom-enabled-themes + (delq theme custom-enabled-themes)))) ;; Only used if window-system not null. (declare-function x-get-resource "frame.c" -- 2.17.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #8: 0007-Minor-cus-theme.el-simplifications.patch --] [-- Type: text/x-diff, Size: 3932 bytes --] From b3d9b63c36f30d6e1feb44d14c608551ccc8665f Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Thu, 10 May 2018 03:08:10 +0100 Subject: [PATCH 7/8] Minor cus-theme.el simplifications * lisp/cus-theme.el (custom-new-theme-mode, customize-themes) (custom-theme-choose-mode): Use setq-local. (customize-create-theme): Ditto. Use delete-all-overlays. (describe-theme-1, custom-theme-summary): Simplify logic. --- lisp/cus-theme.el | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/lisp/cus-theme.el b/lisp/cus-theme.el index 53389956ad..995c55b2b2 100644 --- a/lisp/cus-theme.el +++ b/lisp/cus-theme.el @@ -47,7 +47,7 @@ custom-new-theme-mode Do not call this mode function yourself. It is meant for internal use." (use-local-map custom-new-theme-mode-map) (custom--initialize-widget-variables) - (set (make-local-variable 'revert-buffer-function) #'custom-theme-revert)) + (setq-local revert-buffer-function #'custom-theme-revert)) (put 'custom-new-theme-mode 'mode-class 'special) (defvar custom-theme-name nil) @@ -93,15 +93,14 @@ customize-create-theme (switch-to-buffer (get-buffer-create (or buffer "*Custom Theme*"))) (let ((inhibit-read-only t)) (erase-buffer) - (dolist (ov (overlays-in (point-min) (point-max))) - (delete-overlay ov))) + (delete-all-overlays)) (custom-new-theme-mode) (make-local-variable 'custom-theme-name) - (set (make-local-variable 'custom-theme--save-name) theme) - (set (make-local-variable 'custom-theme-faces) nil) - (set (make-local-variable 'custom-theme-variables) nil) - (set (make-local-variable 'custom-theme-description) "") - (set (make-local-variable 'custom-theme--migrate-settings) nil) + (setq-local custom-theme--save-name theme) + (setq-local custom-theme-faces nil) + (setq-local custom-theme-variables nil) + (setq-local custom-theme-description "") + (setq-local custom-theme--migrate-settings nil) (make-local-variable 'custom-theme-insert-face-marker) (make-local-variable 'custom-theme-insert-variable-marker) (make-local-variable 'custom-theme--listed-faces) @@ -513,8 +512,7 @@ describe-theme-1 (condition-case nil (read (current-buffer)) (end-of-file nil))))) - (and sexp (listp sexp) - (eq (car sexp) 'deftheme) + (and (eq (car-safe sexp) 'deftheme) (setq doc (nth 2 sexp))))))) (princ "\n\nDocumentation:\n") (princ (if (stringp doc) @@ -552,10 +550,10 @@ custom-theme-choose-mode Do not call this mode function yourself. It is meant for internal use." (use-local-map custom-theme-choose-mode-map) (custom--initialize-widget-variables) - (set (make-local-variable 'revert-buffer-function) - (lambda (_ignore-auto noconfirm) - (when (or noconfirm (y-or-n-p "Discard current choices? ")) - (customize-themes (current-buffer)))))) + (setq-local revert-buffer-function + (lambda (_ignore-auto noconfirm) + (when (or noconfirm (y-or-n-p "Discard current choices? ")) + (customize-themes (current-buffer)))))) (put 'custom-theme-choose-mode 'mode-class 'special) ;;;###autoload @@ -568,7 +566,7 @@ customize-themes (let ((inhibit-read-only t)) (erase-buffer)) (custom-theme-choose-mode) - (set (make-local-variable 'custom--listed-themes) nil) + (setq-local custom--listed-themes nil) (make-local-variable 'custom-theme-allow-multiple-selections) (and (null custom-theme-allow-multiple-selections) (> (length custom-enabled-themes) 1) @@ -662,8 +660,7 @@ custom-theme-summary (condition-case nil (read (current-buffer)) (end-of-file nil))))) - (and sexp (listp sexp) - (eq (car sexp) 'deftheme) + (and (eq (car-safe sexp) 'deftheme) (setq doc (nth 2 sexp)))))))) (cond ((null doc) "(no documentation available)") -- 2.17.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #9: 0008-Tweak-subr-x.el-substring-functions.patch --] [-- Type: text/x-diff, Size: 5051 bytes --] From a25af43b28e8a54d5f390c8c13c94609d5cb97e5 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Thu, 3 May 2018 16:12:56 +0100 Subject: [PATCH 8/8] Tweak subr-x.el substring functions * lisp/emacs-lisp/subr-x.el (string-join): #'-quote function symbol. (string-trim-left, string-trim-right, string-remove-suffix): Make better use of substring for minor speedup. * test/lisp/emacs-lisp/subr-x-tests.el (subr-x-test-string-trim-left, subr-x-test-string-trim-right) (subr-x-test-string-remove-prefix) (subr-x-test-string-remove-suffix): New tests. --- lisp/emacs-lisp/subr-x.el | 14 ++++----- test/lisp/emacs-lisp/subr-x-tests.el | 47 ++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 7 deletions(-) diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el index 7fab9083e8..e89b5503a0 100644 --- a/lisp/emacs-lisp/subr-x.el +++ b/lisp/emacs-lisp/subr-x.el @@ -211,7 +211,7 @@ string-empty-p (defsubst string-join (strings &optional separator) "Join all STRINGS using SEPARATOR." - (mapconcat 'identity strings separator)) + (mapconcat #'identity strings separator)) (define-obsolete-function-alias 'string-reverse 'reverse "25.1") @@ -219,17 +219,17 @@ string-trim-left "Trim STRING of leading string matching REGEXP. REGEXP defaults to \"[ \\t\\n\\r]+\"." - (if (string-match (concat "\\`\\(?:" (or regexp "[ \t\n\r]+")"\\)") string) - (replace-match "" t t string) + (if (string-match (concat "\\`\\(?:" (or regexp "[ \t\n\r]+") "\\)") string) + (substring string (match-end 0)) string)) (defsubst string-trim-right (string &optional regexp) "Trim STRING of trailing string matching REGEXP. REGEXP defaults to \"[ \\t\\n\\r]+\"." - (if (string-match (concat "\\(?:" (or regexp "[ \t\n\r]+") "\\)\\'") string) - (replace-match "" t t string) - string)) + (let ((i (string-match-p (concat "\\(?:" (or regexp "[ \t\n\r]+") "\\)\\'") + string))) + (if i (substring string 0 i) string))) (defsubst string-trim (string &optional trim-left trim-right) "Trim STRING of leading and trailing strings matching TRIM-LEFT and TRIM-RIGHT. @@ -250,7 +250,7 @@ string-remove-prefix (defsubst string-remove-suffix (suffix string) "Remove SUFFIX from STRING if present." (if (string-suffix-p suffix string) - (substring string 0 (- (length string) (length suffix))) + (substring string 0 (- (length suffix))) string)) (provide 'subr-x) diff --git a/test/lisp/emacs-lisp/subr-x-tests.el b/test/lisp/emacs-lisp/subr-x-tests.el index f7f0ef384f..81467bab2d 100644 --- a/test/lisp/emacs-lisp/subr-x-tests.el +++ b/test/lisp/emacs-lisp/subr-x-tests.el @@ -532,6 +532,53 @@ (format "abs sum is: %s")) "abs sum is: 15"))) +\f +;; Substring tests + +(ert-deftest subr-x-test-string-trim-left () + "Test `string-trim-left' behavior." + (should (equal (string-trim-left "") "")) + (should (equal (string-trim-left " \t\n\r") "")) + (should (equal (string-trim-left " \t\n\ra") "a")) + (should (equal (string-trim-left "a \t\n\r") "a \t\n\r")) + (should (equal (string-trim-left "" "") "")) + (should (equal (string-trim-left "a" "") "a")) + (should (equal (string-trim-left "aa" "a*") "")) + (should (equal (string-trim-left "ba" "a*") "ba")) + (should (equal (string-trim-left "aa" "a*?") "aa")) + (should (equal (string-trim-left "aa" "a+?") "a"))) + +(ert-deftest subr-x-test-string-trim-right () + "Test `string-trim-right' behavior." + (should (equal (string-trim-right "") "")) + (should (equal (string-trim-right " \t\n\r") "")) + (should (equal (string-trim-right " \t\n\ra") " \t\n\ra")) + (should (equal (string-trim-right "a \t\n\r") "a")) + (should (equal (string-trim-right "" "") "")) + (should (equal (string-trim-right "a" "") "a")) + (should (equal (string-trim-right "aa" "a*") "")) + (should (equal (string-trim-right "ab" "a*") "ab")) + (should (equal (string-trim-right "aa" "a*?") ""))) + +(ert-deftest subr-x-test-string-remove-prefix () + "Test `string-remove-prefix' behavior." + (should (equal (string-remove-prefix "" "") "")) + (should (equal (string-remove-prefix "" "a") "a")) + (should (equal (string-remove-prefix "a" "") "")) + (should (equal (string-remove-prefix "a" "b") "b")) + (should (equal (string-remove-prefix "a" "a") "")) + (should (equal (string-remove-prefix "a" "aa") "a")) + (should (equal (string-remove-prefix "a" "ab") "b"))) + +(ert-deftest subr-x-test-string-remove-suffix () + "Test `string-remove-suffix' behavior." + (should (equal (string-remove-suffix "" "") "")) + (should (equal (string-remove-suffix "" "a") "a")) + (should (equal (string-remove-suffix "a" "") "")) + (should (equal (string-remove-suffix "a" "b") "b")) + (should (equal (string-remove-suffix "a" "a") "")) + (should (equal (string-remove-suffix "a" "aa") "a")) + (should (equal (string-remove-suffix "a" "ba") "b"))) (provide 'subr-x-tests) ;;; subr-x-tests.el ends here -- 2.17.0 ^ permalink raw reply related [flat|nested] 33+ messages in thread
* Re: Byte-compilation of custom themes 2018-06-01 20:48 ` Basil L. Contovounesios @ 2018-06-01 21:07 ` Basil L. Contovounesios 2018-06-02 11:24 ` Eli Zaretskii 1 sibling, 0 replies; 33+ messages in thread From: Basil L. Contovounesios @ 2018-06-01 21:07 UTC (permalink / raw To: Eli Zaretskii; +Cc: monnier, emacs-devel [-- Attachment #1: Type: text/plain, Size: 599 bytes --] "Basil L. Contovounesios" <contovob@tcd.ie> writes: > @@ -250,7 +250,7 @@ string-remove-prefix > (defsubst string-remove-suffix (suffix string) > "Remove SUFFIX from STRING if present." > (if (string-suffix-p suffix string) > - (substring string 0 (- (length string) (length suffix))) > + (substring string 0 (- (length suffix))) > string)) Running the new subr-x-test-string-remove-suffix revealed that there is a bug here when the length of SUFFIX is equal to zero. I reattach the patches with this "simplification" reverted. Sorry about the hassle. Thanks, -- Basil [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: 0001-Improve-loading-of-byte-compiled-custom-themes.patch --] [-- Type: text/x-diff, Size: 4290 bytes --] From d4a711a775649c50e36e4bdc244c79f51ae7a7bc Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Wed, 9 May 2018 22:20:47 +0100 Subject: [PATCH 1/8] Improve loading of byte-compiled custom themes * lisp/custom.el (load-theme): Load byte-compiled file of safe themes when available. https://lists.gnu.org/archive/html/emacs-devel/2018-01/msg00614.html https://lists.gnu.org/archive/html/emacs-devel/2018-02/msg00060.html --- lisp/custom.el | 78 ++++++++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 37 deletions(-) diff --git a/lisp/custom.el b/lisp/custom.el index b7539685a8..1fed5dce53 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -1221,43 +1221,47 @@ load-theme (put theme 'theme-settings nil) (put theme 'theme-feature nil) (put theme 'theme-documentation nil)) - (let ((fn (locate-file (concat (symbol-name theme) "-theme.el") - (custom-theme--load-path) - '("" "c")))) - (unless fn - (error "Unable to find theme file for `%s'" theme)) - (with-temp-buffer - (insert-file-contents fn) - ;; Check file safety with `custom-safe-themes', prompting the - ;; user if necessary. - (when (or no-confirm - (eq custom-safe-themes t) - (and (memq 'default custom-safe-themes) - (equal (file-name-directory fn) - (expand-file-name "themes/" data-directory))) - (let ((hash (secure-hash 'sha256 (current-buffer)))) - (or (member hash custom-safe-themes) - (custom-theme-load-confirm hash)))) - (let ((custom--inhibit-theme-enable t) - (buffer-file-name fn)) ;For load-history. - (eval-buffer)) - ;; Optimization: if the theme changes the `default' face, put that - ;; entry first. This avoids some `frame-set-background-mode' rigmarole - ;; by assigning the new background immediately. - (let* ((settings (get theme 'theme-settings)) - (tail settings) - found) - (while (and tail (not found)) - (and (eq (nth 0 (car tail)) 'theme-face) - (eq (nth 1 (car tail)) 'default) - (setq found (car tail))) - (setq tail (cdr tail))) - (if found - (put theme 'theme-settings (cons found (delq found settings))))) - ;; Finally, enable the theme. - (unless no-enable - (enable-theme theme)) - t)))) + (let ((file (locate-file (concat (symbol-name theme) "-theme.el") + (custom-theme--load-path) + '("" "c"))) + (custom--inhibit-theme-enable t)) + ;; Check file safety with `custom-safe-themes', prompting the + ;; user if necessary. + (cond ((not file) + (error "Unable to find theme file for `%s'" theme)) + ((or no-confirm + (eq custom-safe-themes t) + (and (memq 'default custom-safe-themes) + (equal (file-name-directory file) + (expand-file-name "themes/" data-directory)))) + ;; Theme is safe; load byte-compiled version if available. + (load (file-name-sans-extension file) nil t nil t)) + ((with-temp-buffer + (insert-file-contents file) + (let ((hash (secure-hash 'sha256 (current-buffer)))) + (when (or (member hash custom-safe-themes) + (custom-theme-load-confirm hash)) + (eval-buffer nil nil file) + t)))) + (t + (error "Unable to load theme `%s'" theme)))) + ;; Optimization: if the theme changes the `default' face, put that + ;; entry first. This avoids some `frame-set-background-mode' rigmarole + ;; by assigning the new background immediately. + (let* ((settings (get theme 'theme-settings)) + (tail settings) + found) + (while (and tail (not found)) + (and (eq (nth 0 (car tail)) 'theme-face) + (eq (nth 1 (car tail)) 'default) + (setq found (car tail))) + (setq tail (cdr tail))) + (when found + (put theme 'theme-settings (cons found (delq found settings))))) + ;; Finally, enable the theme. + (unless no-enable + (enable-theme theme)) + t) (defun custom-theme-load-confirm (hash) "Query the user about loading a Custom theme that may not be safe. -- 2.17.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #3: 0002-Disable-no-byte-compile-in-built-in-themes.patch --] [-- Type: text/x-diff, Size: 6291 bytes --] From f625cbdc4dbbcfa59a5773f193e4048bbb024191 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Wed, 9 May 2018 22:30:48 +0100 Subject: [PATCH 2/8] Disable no-byte-compile in built-in themes * etc/themes/adwaita-theme.el: * etc/themes/deeper-blue-theme.el: * etc/themes/dichromacy-theme.el: * etc/themes/leuven-theme.el: * etc/themes/light-blue-theme.el: * etc/themes/manoj-dark-theme.el: * etc/themes/misterioso-theme.el: * etc/themes/tango-dark-theme.el: * etc/themes/tango-theme.el: * etc/themes/tsdh-dark-theme.el: * etc/themes/tsdh-light-theme.el: * etc/themes/wheatgrass-theme.el: * etc/themes/whiteboard-theme.el: * etc/themes/wombat-theme.el: Disable no-byte-compile. https://lists.gnu.org/archive/html/emacs-devel/2018-01/msg00614.html https://lists.gnu.org/archive/html/emacs-devel/2018-02/msg00060.html --- etc/themes/adwaita-theme.el | 4 ---- etc/themes/deeper-blue-theme.el | 4 ---- etc/themes/dichromacy-theme.el | 4 ---- etc/themes/leuven-theme.el | 1 - etc/themes/light-blue-theme.el | 4 ---- etc/themes/manoj-dark-theme.el | 4 ---- etc/themes/misterioso-theme.el | 4 ---- etc/themes/tango-dark-theme.el | 4 ---- etc/themes/tango-theme.el | 4 ---- etc/themes/tsdh-dark-theme.el | 4 ---- etc/themes/tsdh-light-theme.el | 5 ----- etc/themes/wheatgrass-theme.el | 4 ---- etc/themes/whiteboard-theme.el | 4 ---- etc/themes/wombat-theme.el | 4 ---- 14 files changed, 54 deletions(-) diff --git a/etc/themes/adwaita-theme.el b/etc/themes/adwaita-theme.el index b376153510..415db8a191 100644 --- a/etc/themes/adwaita-theme.el +++ b/etc/themes/adwaita-theme.el @@ -99,8 +99,4 @@ adwaita `(diff-added ((,class (:bold t :foreground "#4E9A06")))) `(diff-removed ((,class (:bold t :foreground "#F5666D")))))) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; adwaita-theme.el ends here diff --git a/etc/themes/deeper-blue-theme.el b/etc/themes/deeper-blue-theme.el index c6aa1751f4..0700f4f23d 100644 --- a/etc/themes/deeper-blue-theme.el +++ b/etc/themes/deeper-blue-theme.el @@ -110,8 +110,4 @@ deeper-blue (provide-theme 'deeper-blue) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; deeper-blue-theme.el ends here diff --git a/etc/themes/dichromacy-theme.el b/etc/themes/dichromacy-theme.el index 793209c055..bfced43aee 100644 --- a/etc/themes/dichromacy-theme.el +++ b/etc/themes/dichromacy-theme.el @@ -122,8 +122,4 @@ dichromacy (provide-theme 'dichromacy) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; dichromacy-theme.el ends here diff --git a/etc/themes/leuven-theme.el b/etc/themes/leuven-theme.el index 5c0d19ce81..c3c666588b 100644 --- a/etc/themes/leuven-theme.el +++ b/etc/themes/leuven-theme.el @@ -708,7 +708,6 @@ leuven ;; time-stamp-format: "%:y%02m%02d.%02H%02M" ;; time-stamp-start: "Version: " ;; time-stamp-end: "$" -;; no-byte-compile: t ;; End: ;;; leuven-theme.el ends here diff --git a/etc/themes/light-blue-theme.el b/etc/themes/light-blue-theme.el index 9935c565fb..ba00db6a49 100644 --- a/etc/themes/light-blue-theme.el +++ b/etc/themes/light-blue-theme.el @@ -61,8 +61,4 @@ light-blue (provide-theme 'light-blue) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; light-blue-theme.el ends here diff --git a/etc/themes/manoj-dark-theme.el b/etc/themes/manoj-dark-theme.el index fe61441d78..ddcaa0bd99 100644 --- a/etc/themes/manoj-dark-theme.el +++ b/etc/themes/manoj-dark-theme.el @@ -700,8 +700,4 @@ manoj-dark (provide-theme 'manoj-dark) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; manoj-dark.el ends here diff --git a/etc/themes/misterioso-theme.el b/etc/themes/misterioso-theme.el index 42e448d28b..6c1eec0f42 100644 --- a/etc/themes/misterioso-theme.el +++ b/etc/themes/misterioso-theme.el @@ -103,8 +103,4 @@ misterioso (provide-theme 'misterioso) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; misterioso-theme.el ends here diff --git a/etc/themes/tango-dark-theme.el b/etc/themes/tango-dark-theme.el index 3b6eeb702e..dae77a5e62 100644 --- a/etc/themes/tango-dark-theme.el +++ b/etc/themes/tango-dark-theme.el @@ -170,8 +170,4 @@ tango-dark (provide-theme 'tango-dark) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; tango-dark-theme.el ends here diff --git a/etc/themes/tango-theme.el b/etc/themes/tango-theme.el index a7a79c04ad..4fe2480bc7 100644 --- a/etc/themes/tango-theme.el +++ b/etc/themes/tango-theme.el @@ -154,8 +154,4 @@ tango (provide-theme 'tango) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; tango-theme.el ends here diff --git a/etc/themes/tsdh-dark-theme.el b/etc/themes/tsdh-dark-theme.el index 287fef8253..c216750cb2 100644 --- a/etc/themes/tsdh-dark-theme.el +++ b/etc/themes/tsdh-dark-theme.el @@ -144,8 +144,4 @@ tsdh-dark (provide-theme 'tsdh-dark) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; tsdh-dark-theme.el ends here diff --git a/etc/themes/tsdh-light-theme.el b/etc/themes/tsdh-light-theme.el index 17a86fdbfe..ce9d1a2c3c 100644 --- a/etc/themes/tsdh-light-theme.el +++ b/etc/themes/tsdh-light-theme.el @@ -106,9 +106,4 @@ tsdh-light (provide-theme 'tsdh-light) - -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; tsdh-light-theme.el ends here diff --git a/etc/themes/wheatgrass-theme.el b/etc/themes/wheatgrass-theme.el index 9585e3aa6e..8d34c28bf4 100644 --- a/etc/themes/wheatgrass-theme.el +++ b/etc/themes/wheatgrass-theme.el @@ -83,8 +83,4 @@ wheatgrass (provide-theme 'wheatgrass) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; wheatgrass-theme.el ends here diff --git a/etc/themes/whiteboard-theme.el b/etc/themes/whiteboard-theme.el index 5db0ddd68d..fe46cb0928 100644 --- a/etc/themes/whiteboard-theme.el +++ b/etc/themes/whiteboard-theme.el @@ -100,8 +100,4 @@ whiteboard (provide-theme 'whiteboard) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; whiteboard-theme.el ends here diff --git a/etc/themes/wombat-theme.el b/etc/themes/wombat-theme.el index 583b8dc3f6..00f29bb9fa 100644 --- a/etc/themes/wombat-theme.el +++ b/etc/themes/wombat-theme.el @@ -102,8 +102,4 @@ wombat (provide-theme 'wombat) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; wombat-theme.el ends here -- 2.17.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #4: 0003-Fix-custom-available-themes-file-expansion.patch --] [-- Type: text/x-diff, Size: 6515 bytes --] From 5368d8697d49ae8fb493031be22dee2dbe76624c Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Wed, 2 May 2018 21:18:24 +0100 Subject: [PATCH 3/8] Fix custom-available-themes file expansion For discussion, see thread starting at https://lists.gnu.org/archive/html/emacs-devel/2018-05/msg00222.html. * lisp/custom.el: (custom-available-themes): Use directory-files instead of performing arbitrary wildcard expansion in filenames. (custom-theme--load-path): Document return value. * test/lisp/custom-tests.el: New file. (custom-theme--load-path): New test. --- lisp/custom.el | 22 +++++----- test/lisp/custom-tests.el | 87 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+), 10 deletions(-) create mode 100644 test/lisp/custom-tests.el diff --git a/lisp/custom.el b/lisp/custom.el index 1fed5dce53..157bb318e3 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -1299,19 +1299,21 @@ custom-available-themes loaded, and no effort is made to check that the files contain valid Custom themes. For a list of loaded themes, check the variable `custom-known-themes'." - (let (sym themes) + (let ((suffix "-theme\\.el\\'") + themes) (dolist (dir (custom-theme--load-path)) - (when (file-directory-p dir) - (dolist (file (file-expand-wildcards - (expand-file-name "*-theme.el" dir) t)) - (setq file (file-name-nondirectory file)) - (and (string-match "\\`\\(.+\\)-theme.el\\'" file) - (setq sym (intern (match-string 1 file))) - (custom-theme-name-valid-p sym) - (push sym themes))))) - (nreverse (delete-dups themes)))) + ;; `custom-theme--load-path' promises DIR exists and is a directory. + (dolist (file (directory-files dir nil suffix)) + (let ((theme (intern (substring file 0 (string-match-p suffix file))))) + (and (custom-theme-name-valid-p theme) + (not (memq theme themes)) + (push theme themes))))) + (nreverse themes))) (defun custom-theme--load-path () + "Expand `custom-theme-load-path' into a list of directories. +Members of `custom-theme-load-path' that either don't exist or +are not directories are omitted from the expansion." (let (lpath) (dolist (f custom-theme-load-path) (cond ((eq f 'custom-theme-directory) diff --git a/test/lisp/custom-tests.el b/test/lisp/custom-tests.el new file mode 100644 index 0000000000..96887f8f5f --- /dev/null +++ b/test/lisp/custom-tests.el @@ -0,0 +1,87 @@ +;;; custom-tests.el --- tests for custom.el -*- lexical-binding: t -*- + +;; Copyright (C) 2018 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs 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. + +;; GNU Emacs 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 program. If not, see <https://www.gnu.org/licenses/>. + +;;; Code: + +(require 'ert) + +(ert-deftest custom-theme--load-path () + "Test `custom-theme--load-path' behavior." + (let ((tmpdir (file-name-as-directory (make-temp-file "custom-tests-" t)))) + (unwind-protect + ;; Create all temporary files under the same deletable parent. + (let ((temporary-file-directory tmpdir)) + ;; Path is empty. + (let ((custom-theme-load-path ())) + (should (null (custom-theme--load-path)))) + + ;; Path comprises non-existent file. + (let* ((name (make-temp-name tmpdir)) + (custom-theme-load-path (list name))) + (should (not (file-exists-p name))) + (should (null (custom-theme--load-path)))) + + ;; Path comprises existing file. + (let* ((file (make-temp-file "file")) + (custom-theme-load-path (list file))) + (should (file-exists-p file)) + (should (not (file-directory-p file))) + (should (null (custom-theme--load-path)))) + + ;; Path comprises existing directory. + (let* ((dir (make-temp-file "dir" t)) + (custom-theme-load-path (list dir))) + (should (file-directory-p dir)) + (should (equal (custom-theme--load-path) custom-theme-load-path))) + + ;; Expand `custom-theme-directory' path element. + (let ((custom-theme-load-path '(custom-theme-directory))) + (let ((custom-theme-directory (make-temp-name tmpdir))) + (should (not (file-exists-p custom-theme-directory))) + (should (null (custom-theme--load-path)))) + (let ((custom-theme-directory (make-temp-file "file"))) + (should (file-exists-p custom-theme-directory)) + (should (not (file-directory-p custom-theme-directory))) + (should (null (custom-theme--load-path)))) + (let ((custom-theme-directory (make-temp-file "dir" t))) + (should (file-directory-p custom-theme-directory)) + (should (equal (custom-theme--load-path) + (list custom-theme-directory))))) + + ;; Expand t path element. + (let ((custom-theme-load-path '(t))) + (let ((data-directory (make-temp-name tmpdir))) + (should (not (file-exists-p data-directory))) + (should (null (custom-theme--load-path)))) + (let ((data-directory tmpdir) + (themedir (expand-file-name "themes" tmpdir))) + (should (not (file-exists-p themedir))) + (should (null (custom-theme--load-path))) + (with-temp-file themedir) + (should (file-exists-p themedir)) + (should (not (file-directory-p themedir))) + (should (null (custom-theme--load-path))) + (delete-file themedir) + (make-directory themedir) + (should (file-directory-p themedir)) + (should (equal (custom-theme--load-path) (list themedir)))))) + (when (file-directory-p tmpdir) + (delete-directory tmpdir t))))) + +;;; custom-tests.el ends here -- 2.17.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #5: 0004-lisp-custom.el-Use-lexical-binding.patch --] [-- Type: text/x-diff, Size: 7797 bytes --] From bc839204dfa54de338f33f2814a144fd91ac20ef Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Fri, 11 May 2018 16:09:57 +0100 Subject: [PATCH 4/8] * lisp/custom.el: Use lexical-binding Remove duplicate 'Custom Themes' comment heading. (deftheme, custom-declare-theme): Fix advertised calling convention. (custom-enabled-themes): Fix message grammar. --- lisp/custom.el | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/lisp/custom.el b/lisp/custom.el index 157bb318e3..7ca71dd895 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -1,4 +1,4 @@ -;;; custom.el --- tools for declaring and initializing options +;;; custom.el --- tools for declaring and initializing options -*- lexical-binding: t -*- ;; ;; Copyright (C) 1996-1997, 1999, 2001-2018 Free Software Foundation, ;; Inc. @@ -150,7 +150,7 @@ custom-declare-variable (put symbol 'force-value nil)) (if (keywordp doc) (error "Doc string is missing")) - (let ((initialize 'custom-initialize-reset) + (let ((initialize #'custom-initialize-reset) (requests nil)) (unless (memq :group args) (custom-add-to-group (custom-current-group) symbol 'custom-variable)) @@ -426,7 +426,7 @@ custom-current-group (defun custom-declare-group (symbol members doc &rest args) "Like `defgroup', but SYMBOL is evaluated as a normal argument." (while members - (apply 'custom-add-to-group symbol (car members)) + (apply #'custom-add-to-group symbol (car members)) (setq members (cdr members))) (when doc ;; This text doesn't get into DOC. @@ -618,11 +618,8 @@ custom-note-var-changed The result is that the change is treated as having been made through Custom." (put variable 'customized-value (list (custom-quote (eval variable))))) -\f -;;; Custom Themes - -;;; Loading files needed to customize a symbol. -;;; This is in custom.el because menu-bar.el needs it for toggle cmds. +;; Loading files needed to customize a symbol. +;; This is in custom.el because menu-bar.el needs it for toggle cmds. (defvar custom-load-recursion nil "Hack to avoid recursive dependencies.") @@ -715,7 +712,7 @@ customize-mark-to-save Return non-nil if the `saved-value' property actually changed." (custom-load-symbol symbol) - (let* ((get (or (get symbol 'custom-get) 'default-value)) + (let* ((get (or (get symbol 'custom-get) #'default-value)) (value (funcall get symbol)) (saved (get symbol 'saved-value)) (standard (get symbol 'standard-value)) @@ -744,7 +741,7 @@ customize-mark-as-set Return non-nil if the `customized-value' property actually changed." (custom-load-symbol symbol) - (let* ((get (or (get symbol 'custom-get) 'default-value)) + (let* ((get (or (get symbol 'custom-get) #'default-value)) (value (funcall get symbol)) (customized (get symbol 'customized-value)) (old (or (get symbol 'saved-value) (get symbol 'standard-value)))) @@ -776,7 +773,7 @@ custom-reevaluate-setting ;; always do the funcall step, even if symbol was not bound before. (or (default-boundp symbol) (eval `(defvar ,symbol nil))) ; reset below, so any value is fine - (funcall (or (get symbol 'custom-set) 'set-default) + (funcall (or (get symbol 'custom-set) #'set-default) symbol (eval (car (or (get symbol 'saved-value) (get symbol 'standard-value)))))) @@ -941,7 +938,7 @@ custom-set-variables REQUEST is a list of features we must require in order to handle SYMBOL properly. COMMENT is a comment string about SYMBOL." - (apply 'custom-theme-set-variables 'user args)) + (apply #'custom-theme-set-variables 'user args)) (defun custom-theme-set-variables (theme &rest args) "Initialize variables for theme THEME according to settings in ARGS. @@ -989,8 +986,8 @@ custom-theme-set-variables set) (when requests (put symbol 'custom-requests requests) - (mapc 'require requests)) - (setq set (or (get symbol 'custom-set) 'custom-set-default)) + (mapc #'require requests)) + (setq set (or (get symbol 'custom-set) #'custom-set-default)) (put symbol 'saved-value (list value)) (put symbol 'saved-variable-comment comment) ;; Allow for errors in the case where the setter has @@ -1086,26 +1083,29 @@ custom--sort-vars-1 ;; they were used to supply keyword-value pairs like `:immediate', ;; `:variable-reset-string', etc. We don't use any of these, so ignore them. -(defmacro deftheme (theme &optional doc &rest ignored) +(defmacro deftheme (theme &optional doc &rest _ignored) "Declare THEME to be a Custom theme. The optional argument DOC is a doc string describing the theme. Any theme `foo' should be defined in a file called `foo-theme.el'; see `custom-make-theme-feature' for more information." - (declare (doc-string 2)) + (declare (doc-string 2) + (advertised-calling-convention (theme &optional doc) "22.1")) (let ((feature (custom-make-theme-feature theme))) ;; It is better not to use backquote in this file, ;; because that makes a bootstrapping problem ;; if you need to recompile all the Lisp files using interpreted code. (list 'custom-declare-theme (list 'quote theme) (list 'quote feature) doc))) -(defun custom-declare-theme (theme feature &optional doc &rest ignored) +(defun custom-declare-theme (theme feature &optional doc &rest _ignored) "Like `deftheme', but THEME is evaluated as a normal argument. FEATURE is the feature this theme provides. Normally, this is a symbol created from THEME by `custom-make-theme-feature'." + (declare (advertised-calling-convention (theme feature &optional doc) "22.1")) (unless (custom-theme-name-valid-p theme) (error "Custom theme cannot be named %S" theme)) - (add-to-list 'custom-known-themes theme) + (unless (memq theme custom-known-themes) + (push theme custom-known-themes)) (put theme 'theme-feature feature) (when doc (put theme 'theme-documentation doc))) @@ -1206,7 +1206,7 @@ load-theme (interactive (list (intern (completing-read "Load custom theme: " - (mapcar 'symbol-name + (mapcar #'symbol-name (custom-available-themes)))) nil nil)) (unless (custom-theme-name-valid-p theme) @@ -1391,9 +1391,9 @@ custom-enabled-themes themes (delq theme themes))))) (enable-theme 'user) (custom-set-default symbol themes) - (if failures - (message "Failed to enable theme: %s" - (mapconcat 'symbol-name failures ", ")))))) + (when failures + (message "Failed to enable theme(s): %s" + (mapconcat #'symbol-name failures ", ")))))) (defsubst custom-theme-enabled-p (theme) "Return non-nil if THEME is enabled." @@ -1405,7 +1405,7 @@ disable-theme (interactive (list (intern (completing-read "Disable custom theme: " - (mapcar 'symbol-name custom-enabled-themes) + (mapcar #'symbol-name custom-enabled-themes) nil t)))) (when (custom-theme-enabled-p theme) (let ((settings (get theme 'theme-settings))) @@ -1471,7 +1471,7 @@ custom-theme-recalc-variable (if (and valspec (or (get variable 'force-value) (default-boundp variable))) - (funcall (or (get variable 'custom-set) 'set-default) variable + (funcall (or (get variable 'custom-set) #'set-default) variable (eval (car valspec)))))) (defun custom-theme-recalc-face (face) @@ -1512,7 +1512,7 @@ custom-reset-variables (VARIABLE IGNORED) This means reset VARIABLE. (The argument IGNORED is ignored)." - (apply 'custom-theme-reset-variables 'user args)) + (apply #'custom-theme-reset-variables 'user args)) ;;; The End. -- 2.17.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #6: 0005-lisp-cus-theme.el-Use-lexical-binding.patch --] [-- Type: text/x-diff, Size: 5907 bytes --] From d850fa0df54be25d31b69273722754c3f27e28e5 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Fri, 11 May 2018 15:35:09 +0100 Subject: [PATCH 5/8] * lisp/cus-theme.el: Use lexical-binding --- lisp/cus-theme.el | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/lisp/cus-theme.el b/lisp/cus-theme.el index e5e787771b..53389956ad 100644 --- a/lisp/cus-theme.el +++ b/lisp/cus-theme.el @@ -1,4 +1,4 @@ -;;; cus-theme.el -- custom theme creation user interface +;;; cus-theme.el -- custom theme creation user interface -*- lexical-binding: t -*- ;; ;; Copyright (C) 2001-2018 Free Software Foundation, Inc. ;; @@ -47,7 +47,7 @@ custom-new-theme-mode Do not call this mode function yourself. It is meant for internal use." (use-local-map custom-new-theme-mode-map) (custom--initialize-widget-variables) - (set (make-local-variable 'revert-buffer-function) 'custom-theme-revert)) + (set (make-local-variable 'revert-buffer-function) #'custom-theme-revert)) (put 'custom-new-theme-mode 'mode-class 'special) (defvar custom-theme-name nil) @@ -118,13 +118,13 @@ customize-create-theme :tag " Visit Theme " :help-echo "Insert the settings of a pre-defined theme." :action (lambda (_widget &optional _event) - (call-interactively 'custom-theme-visit-theme))) + (call-interactively #'custom-theme-visit-theme))) (widget-insert " ") (widget-create 'push-button :tag " Merge Theme " :help-echo "Merge in the settings of a pre-defined theme." :action (lambda (_widget &optional _event) - (call-interactively 'custom-theme-merge-theme))) + (call-interactively #'custom-theme-merge-theme))) (widget-insert " ") (widget-create 'push-button :tag " Revert " @@ -142,7 +142,7 @@ customize-create-theme (widget-create 'text :value (format-time-string "Created %Y-%m-%d."))) (widget-create 'push-button - :notify (function custom-theme-write) + :notify #'custom-theme-write " Save Theme ") (when (eq theme 'user) (setq custom-theme--migrate-settings t) @@ -188,7 +188,7 @@ customize-create-theme :mouse-face 'highlight :pressed-face 'highlight :action (lambda (_widget &optional _event) - (call-interactively 'custom-theme-add-face))) + (call-interactively #'custom-theme-add-face))) ;; If THEME is non-nil, insert all of that theme's variables. (widget-insert "\n\n Theme variables:\n ") @@ -207,7 +207,7 @@ customize-create-theme :mouse-face 'highlight :pressed-face 'highlight :action (lambda (_widget &optional _event) - (call-interactively 'custom-theme-add-variable))) + (call-interactively #'custom-theme-add-variable))) (widget-insert ?\n) (widget-setup) (goto-char (point-min)) @@ -254,7 +254,7 @@ custom-theme-add-var-1 :tag (custom-unlispify-tag-name symbol) :value symbol :shown-value (list val) - :notify 'ignore + :notify #'ignore :custom-level 0 :custom-state 'hidden :custom-style 'simple)) @@ -313,7 +313,7 @@ custom-theme-visit-theme (interactive (list (intern (completing-read "Find custom theme: " - (mapcar 'symbol-name + (mapcar #'symbol-name (custom-available-themes)))))) (unless (custom-theme-name-valid-p theme) (error "No valid theme named `%s'" theme)) @@ -328,7 +328,7 @@ custom-theme-merge-theme (interactive (list (intern (completing-read "Merge custom theme: " - (mapcar 'symbol-name + (mapcar #'symbol-name (custom-available-themes)))))) (unless (eq theme 'user) (unless (custom-theme-name-valid-p theme) @@ -343,8 +343,8 @@ custom-theme-merge-theme (memq name '(custom-enabled-themes custom-safe-themes))) (funcall (if option - 'custom-theme-add-variable - 'custom-theme-add-face) + #'custom-theme-add-variable + #'custom-theme-add-face) name value))))) theme) @@ -475,7 +475,7 @@ describe-theme (interactive (list (intern (completing-read "Describe custom theme: " - (mapcar 'symbol-name + (mapcar #'symbol-name (custom-available-themes)))))) (unless (custom-theme-name-valid-p theme) (error "Invalid theme name `%s'" theme)) @@ -616,11 +616,11 @@ customize-themes (widget-create 'push-button :tag " Save Theme Settings " :help-echo "Save the selected themes for future sessions." - :action 'custom-theme-save) + :action #'custom-theme-save) (widget-insert ?\n) (widget-create 'checkbox :value custom-theme-allow-multiple-selections - :action 'custom-theme-selections-toggle) + :action #'custom-theme-selections-toggle) (widget-insert (propertize " Select more than one theme at a time" 'face '(variable-pitch (:height 0.9)))) @@ -632,13 +632,13 @@ customize-themes :value (custom-theme-enabled-p theme) :theme-name theme :help-echo help-echo - :action 'custom-theme-checkbox-toggle)) + :action #'custom-theme-checkbox-toggle)) (push (cons theme widget) custom--listed-themes) (widget-create-child-and-convert widget 'push-button :button-face-get 'ignore :mouse-face-get 'ignore :value (format " %s" theme) - :action 'widget-parent-action + :action #'widget-parent-action :help-echo help-echo) (widget-insert " -- " (propertize (custom-theme-summary theme) -- 2.17.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #7: 0006-Minor-custom.el-simplifications.patch --] [-- Type: text/x-diff, Size: 7892 bytes --] From 531b5169240c4f7a39a3eabfec78154789d48fdc Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Thu, 31 May 2018 18:37:02 +0100 Subject: [PATCH 6/8] Minor custom.el simplifications * lisp/custom.el (custom-quote): Duplicate macroexp-quote. (custom-load-symbol, customize-mark-to-save, customize-mark-as-set) (custom-theme-name-valid-p, enable-theme, custom-enabled-themes) (disable-theme): Simplify logic. --- lisp/custom.el | 103 ++++++++++++++++++++++--------------------------- 1 file changed, 46 insertions(+), 57 deletions(-) diff --git a/lisp/custom.el b/lisp/custom.el index 7ca71dd895..076790b661 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -630,14 +630,12 @@ custom-load-symbol (let ((custom-load-recursion t)) ;; Load these files if not already done, ;; to make sure we know all the dependencies of SYMBOL. - (condition-case nil - (require 'cus-load) - (error nil)) - (condition-case nil - (require 'cus-start) - (error nil)) + (ignore-errors + (require 'cus-load)) + (ignore-errors + (require 'cus-start)) (dolist (load (get symbol 'custom-loads)) - (cond ((symbolp load) (condition-case nil (require load) (error nil))) + (cond ((symbolp load) (ignore-errors (require load))) ;; This is subsumed by the test below, but it's much faster. ((assoc load load-history)) ;; This was just (assoc (locate-library load) load-history) @@ -655,7 +653,7 @@ custom-load-symbol ;; We are still loading it when we call this, ;; and it is not in load-history yet. ((equal load "cus-edit")) - (t (condition-case nil (load load) (error nil)))))))) + (t (ignore-errors (load load)))))))) \f (defvar custom-local-buffer nil "Non-nil, in a Customization buffer, means customize a specific buffer. @@ -688,16 +686,12 @@ custom-set-minor-mode (defun custom-quote (sexp) "Quote SEXP if it is not self quoting." - (if (or (memq sexp '(t nil)) - (keywordp sexp) - (and (listp sexp) - (memq (car sexp) '(lambda))) - (stringp sexp) - (numberp sexp) - (vectorp sexp) -;;; (and (fboundp 'characterp) -;;; (characterp sexp)) - ) + ;; Can't use `macroexp-quote' because it is loaded after `custom.el' + ;; during bootstrap. See `loadup.el'. + (if (and (not (consp sexp)) + (or (keywordp sexp) + (not (symbolp sexp)) + (booleanp sexp))) sexp (list 'quote sexp))) @@ -718,12 +712,10 @@ customize-mark-to-save (standard (get symbol 'standard-value)) (comment (get symbol 'customized-variable-comment))) ;; Save default value if different from standard value. - (if (or (null standard) - (not (equal value (condition-case nil - (eval (car standard)) - (error nil))))) - (put symbol 'saved-value (list (custom-quote value))) - (put symbol 'saved-value nil)) + (put symbol 'saved-value + (unless (and standard + (equal value (ignore-errors (eval (car standard))))) + (list (custom-quote value)))) ;; Clear customized information (set, but not saved). (put symbol 'customized-value nil) ;; Save any comment that might have been set. @@ -747,9 +739,8 @@ customize-mark-as-set (old (or (get symbol 'saved-value) (get symbol 'standard-value)))) ;; Mark default value as set if different from old value. (if (not (and old - (equal value (condition-case nil - (eval (car old)) - (error nil))))) + (equal value (ignore-errors + (eval (car old)))))) (progn (put symbol 'customized-value (list (custom-quote value))) (custom-push-theme 'theme-value symbol 'user 'set (custom-quote value))) @@ -1284,11 +1275,9 @@ custom-theme-load-confirm (defun custom-theme-name-valid-p (name) "Return t if NAME is a valid name for a Custom theme, nil otherwise. NAME should be a symbol." - (and (symbolp name) - name - (not (or (zerop (length (symbol-name name))) - (eq name 'user) - (eq name 'changed))))) + (and (not (memq name '(nil user changed))) + (symbolp name) + (not (string= "" (symbol-name name))))) (defun custom-available-themes () "Return a list of Custom themes available for loading. @@ -1336,8 +1325,8 @@ enable-theme (completing-read "Enable custom theme: " obarray (lambda (sym) (get sym 'theme-settings)) t)))) - (if (not (custom-theme-p theme)) - (error "Undefined Custom theme %s" theme)) + (unless (custom-theme-p theme) + (error "Undefined Custom theme %s" theme)) (let ((settings (get theme 'theme-settings))) ;; Loop through theme settings, recalculating vars/faces. (dolist (s settings) @@ -1377,18 +1366,18 @@ custom-enabled-themes (let (failures) (setq themes (delq 'user (delete-dups themes))) ;; Disable all themes not in THEMES. - (if (boundp symbol) - (dolist (theme (symbol-value symbol)) - (if (not (memq theme themes)) - (disable-theme theme)))) + (dolist (theme (and (boundp symbol) + (symbol-value symbol))) + (unless (memq theme themes) + (disable-theme theme))) ;; Call `enable-theme' or `load-theme' on each of THEMES. (dolist (theme (reverse themes)) (condition-case nil (if (custom-theme-p theme) (enable-theme theme) (load-theme theme)) - (error (setq failures (cons theme failures) - themes (delq theme themes))))) + (error (push theme failures) + (setq themes (delq theme themes))))) (enable-theme 'user) (custom-set-default symbol themes) (when failures @@ -1421,23 +1410,23 @@ disable-theme ;; If the face spec specified by this theme is in the ;; saved-face property, reset that property. (when (equal (nth 3 s) (get symbol 'saved-face)) - (put symbol 'saved-face (and val (cadr (car val))))))))) - ;; Recompute faces on all frames. - (dolist (frame (frame-list)) - ;; We must reset the fg and bg color frame parameters, or - ;; `face-set-after-frame-default' will use the existing - ;; parameters, which could be from the disabled theme. - (set-frame-parameter frame 'background-color - (custom--frame-color-default - frame :background "background" "Background" - "unspecified-bg" "white")) - (set-frame-parameter frame 'foreground-color - (custom--frame-color-default - frame :foreground "foreground" "Foreground" - "unspecified-fg" "black")) - (face-set-after-frame-default frame)) - (setq custom-enabled-themes - (delq theme custom-enabled-themes))))) + (put symbol 'saved-face (cadar val)))))))) + ;; Recompute faces on all frames. + (dolist (frame (frame-list)) + ;; We must reset the fg and bg color frame parameters, or + ;; `face-set-after-frame-default' will use the existing + ;; parameters, which could be from the disabled theme. + (set-frame-parameter frame 'background-color + (custom--frame-color-default + frame :background "background" "Background" + "unspecified-bg" "white")) + (set-frame-parameter frame 'foreground-color + (custom--frame-color-default + frame :foreground "foreground" "Foreground" + "unspecified-fg" "black")) + (face-set-after-frame-default frame)) + (setq custom-enabled-themes + (delq theme custom-enabled-themes)))) ;; Only used if window-system not null. (declare-function x-get-resource "frame.c" -- 2.17.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #8: 0007-Minor-cus-theme.el-simplifications.patch --] [-- Type: text/x-diff, Size: 3932 bytes --] From b3d9b63c36f30d6e1feb44d14c608551ccc8665f Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Thu, 10 May 2018 03:08:10 +0100 Subject: [PATCH 7/8] Minor cus-theme.el simplifications * lisp/cus-theme.el (custom-new-theme-mode, customize-themes) (custom-theme-choose-mode): Use setq-local. (customize-create-theme): Ditto. Use delete-all-overlays. (describe-theme-1, custom-theme-summary): Simplify logic. --- lisp/cus-theme.el | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/lisp/cus-theme.el b/lisp/cus-theme.el index 53389956ad..995c55b2b2 100644 --- a/lisp/cus-theme.el +++ b/lisp/cus-theme.el @@ -47,7 +47,7 @@ custom-new-theme-mode Do not call this mode function yourself. It is meant for internal use." (use-local-map custom-new-theme-mode-map) (custom--initialize-widget-variables) - (set (make-local-variable 'revert-buffer-function) #'custom-theme-revert)) + (setq-local revert-buffer-function #'custom-theme-revert)) (put 'custom-new-theme-mode 'mode-class 'special) (defvar custom-theme-name nil) @@ -93,15 +93,14 @@ customize-create-theme (switch-to-buffer (get-buffer-create (or buffer "*Custom Theme*"))) (let ((inhibit-read-only t)) (erase-buffer) - (dolist (ov (overlays-in (point-min) (point-max))) - (delete-overlay ov))) + (delete-all-overlays)) (custom-new-theme-mode) (make-local-variable 'custom-theme-name) - (set (make-local-variable 'custom-theme--save-name) theme) - (set (make-local-variable 'custom-theme-faces) nil) - (set (make-local-variable 'custom-theme-variables) nil) - (set (make-local-variable 'custom-theme-description) "") - (set (make-local-variable 'custom-theme--migrate-settings) nil) + (setq-local custom-theme--save-name theme) + (setq-local custom-theme-faces nil) + (setq-local custom-theme-variables nil) + (setq-local custom-theme-description "") + (setq-local custom-theme--migrate-settings nil) (make-local-variable 'custom-theme-insert-face-marker) (make-local-variable 'custom-theme-insert-variable-marker) (make-local-variable 'custom-theme--listed-faces) @@ -513,8 +512,7 @@ describe-theme-1 (condition-case nil (read (current-buffer)) (end-of-file nil))))) - (and sexp (listp sexp) - (eq (car sexp) 'deftheme) + (and (eq (car-safe sexp) 'deftheme) (setq doc (nth 2 sexp))))))) (princ "\n\nDocumentation:\n") (princ (if (stringp doc) @@ -552,10 +550,10 @@ custom-theme-choose-mode Do not call this mode function yourself. It is meant for internal use." (use-local-map custom-theme-choose-mode-map) (custom--initialize-widget-variables) - (set (make-local-variable 'revert-buffer-function) - (lambda (_ignore-auto noconfirm) - (when (or noconfirm (y-or-n-p "Discard current choices? ")) - (customize-themes (current-buffer)))))) + (setq-local revert-buffer-function + (lambda (_ignore-auto noconfirm) + (when (or noconfirm (y-or-n-p "Discard current choices? ")) + (customize-themes (current-buffer)))))) (put 'custom-theme-choose-mode 'mode-class 'special) ;;;###autoload @@ -568,7 +566,7 @@ customize-themes (let ((inhibit-read-only t)) (erase-buffer)) (custom-theme-choose-mode) - (set (make-local-variable 'custom--listed-themes) nil) + (setq-local custom--listed-themes nil) (make-local-variable 'custom-theme-allow-multiple-selections) (and (null custom-theme-allow-multiple-selections) (> (length custom-enabled-themes) 1) @@ -662,8 +660,7 @@ custom-theme-summary (condition-case nil (read (current-buffer)) (end-of-file nil))))) - (and sexp (listp sexp) - (eq (car sexp) 'deftheme) + (and (eq (car-safe sexp) 'deftheme) (setq doc (nth 2 sexp)))))))) (cond ((null doc) "(no documentation available)") -- 2.17.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #9: 0008-Tweak-subr-x.el-substring-functions.patch --] [-- Type: text/x-diff, Size: 4709 bytes --] From 36e9ae0e7cfff1a466db085997a9e67d027e0a99 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Fri, 1 Jun 2018 21:58:10 +0100 Subject: [PATCH 8/8] Tweak subr-x.el substring functions * lisp/emacs-lisp/subr-x.el (string-join): #'-quote function symbol. (string-trim-left, string-trim-right): Make better use of substring for minor speedup. * test/lisp/emacs-lisp/subr-x-tests.el (subr-x-test-string-trim-left, subr-x-test-string-trim-right) (subr-x-test-string-remove-prefix) (subr-x-test-string-remove-suffix): New tests. --- lisp/emacs-lisp/subr-x.el | 12 +++---- test/lisp/emacs-lisp/subr-x-tests.el | 47 ++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el index 7fab9083e8..eb3ec85ecc 100644 --- a/lisp/emacs-lisp/subr-x.el +++ b/lisp/emacs-lisp/subr-x.el @@ -211,7 +211,7 @@ string-empty-p (defsubst string-join (strings &optional separator) "Join all STRINGS using SEPARATOR." - (mapconcat 'identity strings separator)) + (mapconcat #'identity strings separator)) (define-obsolete-function-alias 'string-reverse 'reverse "25.1") @@ -219,17 +219,17 @@ string-trim-left "Trim STRING of leading string matching REGEXP. REGEXP defaults to \"[ \\t\\n\\r]+\"." - (if (string-match (concat "\\`\\(?:" (or regexp "[ \t\n\r]+")"\\)") string) - (replace-match "" t t string) + (if (string-match (concat "\\`\\(?:" (or regexp "[ \t\n\r]+") "\\)") string) + (substring string (match-end 0)) string)) (defsubst string-trim-right (string &optional regexp) "Trim STRING of trailing string matching REGEXP. REGEXP defaults to \"[ \\t\\n\\r]+\"." - (if (string-match (concat "\\(?:" (or regexp "[ \t\n\r]+") "\\)\\'") string) - (replace-match "" t t string) - string)) + (let ((i (string-match-p (concat "\\(?:" (or regexp "[ \t\n\r]+") "\\)\\'") + string))) + (if i (substring string 0 i) string))) (defsubst string-trim (string &optional trim-left trim-right) "Trim STRING of leading and trailing strings matching TRIM-LEFT and TRIM-RIGHT. diff --git a/test/lisp/emacs-lisp/subr-x-tests.el b/test/lisp/emacs-lisp/subr-x-tests.el index f7f0ef384f..81467bab2d 100644 --- a/test/lisp/emacs-lisp/subr-x-tests.el +++ b/test/lisp/emacs-lisp/subr-x-tests.el @@ -532,6 +532,53 @@ (format "abs sum is: %s")) "abs sum is: 15"))) +\f +;; Substring tests + +(ert-deftest subr-x-test-string-trim-left () + "Test `string-trim-left' behavior." + (should (equal (string-trim-left "") "")) + (should (equal (string-trim-left " \t\n\r") "")) + (should (equal (string-trim-left " \t\n\ra") "a")) + (should (equal (string-trim-left "a \t\n\r") "a \t\n\r")) + (should (equal (string-trim-left "" "") "")) + (should (equal (string-trim-left "a" "") "a")) + (should (equal (string-trim-left "aa" "a*") "")) + (should (equal (string-trim-left "ba" "a*") "ba")) + (should (equal (string-trim-left "aa" "a*?") "aa")) + (should (equal (string-trim-left "aa" "a+?") "a"))) + +(ert-deftest subr-x-test-string-trim-right () + "Test `string-trim-right' behavior." + (should (equal (string-trim-right "") "")) + (should (equal (string-trim-right " \t\n\r") "")) + (should (equal (string-trim-right " \t\n\ra") " \t\n\ra")) + (should (equal (string-trim-right "a \t\n\r") "a")) + (should (equal (string-trim-right "" "") "")) + (should (equal (string-trim-right "a" "") "a")) + (should (equal (string-trim-right "aa" "a*") "")) + (should (equal (string-trim-right "ab" "a*") "ab")) + (should (equal (string-trim-right "aa" "a*?") ""))) + +(ert-deftest subr-x-test-string-remove-prefix () + "Test `string-remove-prefix' behavior." + (should (equal (string-remove-prefix "" "") "")) + (should (equal (string-remove-prefix "" "a") "a")) + (should (equal (string-remove-prefix "a" "") "")) + (should (equal (string-remove-prefix "a" "b") "b")) + (should (equal (string-remove-prefix "a" "a") "")) + (should (equal (string-remove-prefix "a" "aa") "a")) + (should (equal (string-remove-prefix "a" "ab") "b"))) + +(ert-deftest subr-x-test-string-remove-suffix () + "Test `string-remove-suffix' behavior." + (should (equal (string-remove-suffix "" "") "")) + (should (equal (string-remove-suffix "" "a") "a")) + (should (equal (string-remove-suffix "a" "") "")) + (should (equal (string-remove-suffix "a" "b") "b")) + (should (equal (string-remove-suffix "a" "a") "")) + (should (equal (string-remove-suffix "a" "aa") "a")) + (should (equal (string-remove-suffix "a" "ba") "b"))) (provide 'subr-x-tests) ;;; subr-x-tests.el ends here -- 2.17.0 ^ permalink raw reply related [flat|nested] 33+ messages in thread
* Re: Byte-compilation of custom themes 2018-06-01 20:48 ` Basil L. Contovounesios 2018-06-01 21:07 ` Basil L. Contovounesios @ 2018-06-02 11:24 ` Eli Zaretskii 2018-06-02 18:53 ` Basil L. Contovounesios 1 sibling, 1 reply; 33+ messages in thread From: Eli Zaretskii @ 2018-06-02 11:24 UTC (permalink / raw To: Basil L. Contovounesios; +Cc: monnier, emacs-devel > From: "Basil L. Contovounesios" <contovob@tcd.ie> > Cc: <monnier@IRO.UMontreal.CA>, <emacs-devel@gnu.org> > Date: Fri, 01 Jun 2018 21:48:21 +0100 > > >> Do you mean a cl-assertion, or an emulation thereof? > > > > I meant cl-assert. > > Unless I (being unfamiliar with the subtleties of the build and > bootstrap process) am missing something, I think it's too early to load > cl-lib here; at least 'make bootstrap' fails for me when I add > (eval-when-compile (require 'cl-lib)) to custom.el. Is there a way > around this? Yes, explicitly check whether cl-lib is available, and skip the call if not. We don't need this assertion during the bootstrap. > >> Either way, what is the benefit of barfing before directory-files does? > > > > That you can control the text of the error message, and make it more > > user-friendly. Also, an assertion clearly means we intended this not > > to happen, rather than that the code failed to handle some valid > > situation. > > Understood. I've noticed, however, that many, if not most, uses of > cl-assert don't specify a custom error message. For future reference, > is this acceptable practice, or would we rather see consistent use of > more informative messages? My preference is clear from the above, but I don't have enough experience to answer the rest of your question. Thanks. ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Byte-compilation of custom themes 2018-06-02 11:24 ` Eli Zaretskii @ 2018-06-02 18:53 ` Basil L. Contovounesios 2018-06-02 19:32 ` Eli Zaretskii 0 siblings, 1 reply; 33+ messages in thread From: Basil L. Contovounesios @ 2018-06-02 18:53 UTC (permalink / raw To: Eli Zaretskii; +Cc: monnier, emacs-devel [-- Attachment #1: Type: text/plain, Size: 1018 bytes --] Eli Zaretskii <eliz@gnu.org> writes: >> From: "Basil L. Contovounesios" <contovob@tcd.ie> >> Cc: <monnier@IRO.UMontreal.CA>, <emacs-devel@gnu.org> >> Date: Fri, 01 Jun 2018 21:48:21 +0100 >> >> >> Do you mean a cl-assertion, or an emulation thereof? >> > >> > I meant cl-assert. >> >> Unless I (being unfamiliar with the subtleties of the build and >> bootstrap process) am missing something, I think it's too early to load >> cl-lib here; at least 'make bootstrap' fails for me when I add >> (eval-when-compile (require 'cl-lib)) to custom.el. Is there a way >> around this? > > Yes, explicitly check whether cl-lib is available, and skip the call > if not. We don't need this assertion during the bootstrap. It somehow evaded me until now that cl-assert has an autoload cookie. This means I can get away with calling it in custom-available-themes without first requiring cl-lib, whether at top-level or inside the function, right? In other words, is the following kosher (and is the wording up to scratch)? [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: assert.diff --] [-- Type: text/x-diff, Size: 655 bytes --] diff --git a/lisp/custom.el b/lisp/custom.el index 076790b661..f08a8e9c3e 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -1291,7 +1291,9 @@ custom-available-themes (let ((suffix "-theme\\.el\\'") themes) (dolist (dir (custom-theme--load-path)) - ;; `custom-theme--load-path' promises DIR exists and is a directory. + (cl-assert + (file-directory-p dir) t + "Non-existent directory in `custom-theme-load-path' expansion: %s") (dolist (file (directory-files dir nil suffix)) (let ((theme (intern (substring file 0 (string-match-p suffix file))))) (and (custom-theme-name-valid-p theme) [-- Attachment #3: Type: text/plain, Size: 569 bytes --] If not, WDYM exactly by "check whether cl-lib is available"? Passing a non-nil NOERROR argument to a top-level (eval-when-compile (require 'cl-lib nil t)) still causes 'make bootstrap' to fail, and writing (when (require/featurep/fboundp ...) (cl-assert ...)) in custom-available-themes doesn't make sense to me, especially given that cl-assert is autoloaded. Am I misunderstanding something? Sorry about my slow uptake on this; I'm not deliberately trying to be obtuse, rather trying to learn what the best approach is here and why. Thanks, -- Basil ^ permalink raw reply related [flat|nested] 33+ messages in thread
* Re: Byte-compilation of custom themes 2018-06-02 18:53 ` Basil L. Contovounesios @ 2018-06-02 19:32 ` Eli Zaretskii 2018-06-02 20:02 ` Basil L. Contovounesios 2018-06-03 3:52 ` Stefan Monnier 0 siblings, 2 replies; 33+ messages in thread From: Eli Zaretskii @ 2018-06-02 19:32 UTC (permalink / raw To: Basil L. Contovounesios; +Cc: monnier, emacs-devel > From: "Basil L. Contovounesios" <contovob@tcd.ie> > Cc: <monnier@IRO.UMontreal.CA>, <emacs-devel@gnu.org> > Date: Sat, 02 Jun 2018 19:53:09 +0100 > > It somehow evaded me until now that cl-assert has an autoload cookie. > This means I can get away with calling it in custom-available-themes > without first requiring cl-lib, whether at top-level or inside the > function, right? In other words, is the following kosher (and is the > wording up to scratch)? Yes, I think so. > If not, WDYM exactly by "check whether cl-lib is available"? I meant featurep, but since cl-assert is autoloaded, that shouldn't be needed. ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Byte-compilation of custom themes 2018-06-02 19:32 ` Eli Zaretskii @ 2018-06-02 20:02 ` Basil L. Contovounesios 2018-06-03 3:52 ` Stefan Monnier 1 sibling, 0 replies; 33+ messages in thread From: Basil L. Contovounesios @ 2018-06-02 20:02 UTC (permalink / raw To: Eli Zaretskii; +Cc: monnier, emacs-devel [-- Attachment #1: Type: text/plain, Size: 615 bytes --] Eli Zaretskii <eliz@gnu.org> writes: >> From: "Basil L. Contovounesios" <contovob@tcd.ie> >> Cc: <monnier@IRO.UMontreal.CA>, <emacs-devel@gnu.org> >> Date: Sat, 02 Jun 2018 19:53:09 +0100 >> >> It somehow evaded me until now that cl-assert has an autoload cookie. >> This means I can get away with calling it in custom-available-themes >> without first requiring cl-lib, whether at top-level or inside the >> function, right? In other words, is the following kosher (and is the >> wording up to scratch)? > > Yes, I think so. I reattach the patches with the third one updated accordingly. Thanks, -- Basil [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: 0001-Improve-loading-of-byte-compiled-custom-themes.patch --] [-- Type: text/x-diff, Size: 4290 bytes --] From d4a711a775649c50e36e4bdc244c79f51ae7a7bc Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Wed, 9 May 2018 22:20:47 +0100 Subject: [PATCH 1/8] Improve loading of byte-compiled custom themes * lisp/custom.el (load-theme): Load byte-compiled file of safe themes when available. https://lists.gnu.org/archive/html/emacs-devel/2018-01/msg00614.html https://lists.gnu.org/archive/html/emacs-devel/2018-02/msg00060.html --- lisp/custom.el | 78 ++++++++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 37 deletions(-) diff --git a/lisp/custom.el b/lisp/custom.el index b7539685a8..1fed5dce53 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -1221,43 +1221,47 @@ load-theme (put theme 'theme-settings nil) (put theme 'theme-feature nil) (put theme 'theme-documentation nil)) - (let ((fn (locate-file (concat (symbol-name theme) "-theme.el") - (custom-theme--load-path) - '("" "c")))) - (unless fn - (error "Unable to find theme file for `%s'" theme)) - (with-temp-buffer - (insert-file-contents fn) - ;; Check file safety with `custom-safe-themes', prompting the - ;; user if necessary. - (when (or no-confirm - (eq custom-safe-themes t) - (and (memq 'default custom-safe-themes) - (equal (file-name-directory fn) - (expand-file-name "themes/" data-directory))) - (let ((hash (secure-hash 'sha256 (current-buffer)))) - (or (member hash custom-safe-themes) - (custom-theme-load-confirm hash)))) - (let ((custom--inhibit-theme-enable t) - (buffer-file-name fn)) ;For load-history. - (eval-buffer)) - ;; Optimization: if the theme changes the `default' face, put that - ;; entry first. This avoids some `frame-set-background-mode' rigmarole - ;; by assigning the new background immediately. - (let* ((settings (get theme 'theme-settings)) - (tail settings) - found) - (while (and tail (not found)) - (and (eq (nth 0 (car tail)) 'theme-face) - (eq (nth 1 (car tail)) 'default) - (setq found (car tail))) - (setq tail (cdr tail))) - (if found - (put theme 'theme-settings (cons found (delq found settings))))) - ;; Finally, enable the theme. - (unless no-enable - (enable-theme theme)) - t)))) + (let ((file (locate-file (concat (symbol-name theme) "-theme.el") + (custom-theme--load-path) + '("" "c"))) + (custom--inhibit-theme-enable t)) + ;; Check file safety with `custom-safe-themes', prompting the + ;; user if necessary. + (cond ((not file) + (error "Unable to find theme file for `%s'" theme)) + ((or no-confirm + (eq custom-safe-themes t) + (and (memq 'default custom-safe-themes) + (equal (file-name-directory file) + (expand-file-name "themes/" data-directory)))) + ;; Theme is safe; load byte-compiled version if available. + (load (file-name-sans-extension file) nil t nil t)) + ((with-temp-buffer + (insert-file-contents file) + (let ((hash (secure-hash 'sha256 (current-buffer)))) + (when (or (member hash custom-safe-themes) + (custom-theme-load-confirm hash)) + (eval-buffer nil nil file) + t)))) + (t + (error "Unable to load theme `%s'" theme)))) + ;; Optimization: if the theme changes the `default' face, put that + ;; entry first. This avoids some `frame-set-background-mode' rigmarole + ;; by assigning the new background immediately. + (let* ((settings (get theme 'theme-settings)) + (tail settings) + found) + (while (and tail (not found)) + (and (eq (nth 0 (car tail)) 'theme-face) + (eq (nth 1 (car tail)) 'default) + (setq found (car tail))) + (setq tail (cdr tail))) + (when found + (put theme 'theme-settings (cons found (delq found settings))))) + ;; Finally, enable the theme. + (unless no-enable + (enable-theme theme)) + t) (defun custom-theme-load-confirm (hash) "Query the user about loading a Custom theme that may not be safe. -- 2.17.1 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #3: 0002-Disable-no-byte-compile-in-built-in-themes.patch --] [-- Type: text/x-diff, Size: 6291 bytes --] From f625cbdc4dbbcfa59a5773f193e4048bbb024191 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Wed, 9 May 2018 22:30:48 +0100 Subject: [PATCH 2/8] Disable no-byte-compile in built-in themes * etc/themes/adwaita-theme.el: * etc/themes/deeper-blue-theme.el: * etc/themes/dichromacy-theme.el: * etc/themes/leuven-theme.el: * etc/themes/light-blue-theme.el: * etc/themes/manoj-dark-theme.el: * etc/themes/misterioso-theme.el: * etc/themes/tango-dark-theme.el: * etc/themes/tango-theme.el: * etc/themes/tsdh-dark-theme.el: * etc/themes/tsdh-light-theme.el: * etc/themes/wheatgrass-theme.el: * etc/themes/whiteboard-theme.el: * etc/themes/wombat-theme.el: Disable no-byte-compile. https://lists.gnu.org/archive/html/emacs-devel/2018-01/msg00614.html https://lists.gnu.org/archive/html/emacs-devel/2018-02/msg00060.html --- etc/themes/adwaita-theme.el | 4 ---- etc/themes/deeper-blue-theme.el | 4 ---- etc/themes/dichromacy-theme.el | 4 ---- etc/themes/leuven-theme.el | 1 - etc/themes/light-blue-theme.el | 4 ---- etc/themes/manoj-dark-theme.el | 4 ---- etc/themes/misterioso-theme.el | 4 ---- etc/themes/tango-dark-theme.el | 4 ---- etc/themes/tango-theme.el | 4 ---- etc/themes/tsdh-dark-theme.el | 4 ---- etc/themes/tsdh-light-theme.el | 5 ----- etc/themes/wheatgrass-theme.el | 4 ---- etc/themes/whiteboard-theme.el | 4 ---- etc/themes/wombat-theme.el | 4 ---- 14 files changed, 54 deletions(-) diff --git a/etc/themes/adwaita-theme.el b/etc/themes/adwaita-theme.el index b376153510..415db8a191 100644 --- a/etc/themes/adwaita-theme.el +++ b/etc/themes/adwaita-theme.el @@ -99,8 +99,4 @@ adwaita `(diff-added ((,class (:bold t :foreground "#4E9A06")))) `(diff-removed ((,class (:bold t :foreground "#F5666D")))))) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; adwaita-theme.el ends here diff --git a/etc/themes/deeper-blue-theme.el b/etc/themes/deeper-blue-theme.el index c6aa1751f4..0700f4f23d 100644 --- a/etc/themes/deeper-blue-theme.el +++ b/etc/themes/deeper-blue-theme.el @@ -110,8 +110,4 @@ deeper-blue (provide-theme 'deeper-blue) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; deeper-blue-theme.el ends here diff --git a/etc/themes/dichromacy-theme.el b/etc/themes/dichromacy-theme.el index 793209c055..bfced43aee 100644 --- a/etc/themes/dichromacy-theme.el +++ b/etc/themes/dichromacy-theme.el @@ -122,8 +122,4 @@ dichromacy (provide-theme 'dichromacy) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; dichromacy-theme.el ends here diff --git a/etc/themes/leuven-theme.el b/etc/themes/leuven-theme.el index 5c0d19ce81..c3c666588b 100644 --- a/etc/themes/leuven-theme.el +++ b/etc/themes/leuven-theme.el @@ -708,7 +708,6 @@ leuven ;; time-stamp-format: "%:y%02m%02d.%02H%02M" ;; time-stamp-start: "Version: " ;; time-stamp-end: "$" -;; no-byte-compile: t ;; End: ;;; leuven-theme.el ends here diff --git a/etc/themes/light-blue-theme.el b/etc/themes/light-blue-theme.el index 9935c565fb..ba00db6a49 100644 --- a/etc/themes/light-blue-theme.el +++ b/etc/themes/light-blue-theme.el @@ -61,8 +61,4 @@ light-blue (provide-theme 'light-blue) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; light-blue-theme.el ends here diff --git a/etc/themes/manoj-dark-theme.el b/etc/themes/manoj-dark-theme.el index fe61441d78..ddcaa0bd99 100644 --- a/etc/themes/manoj-dark-theme.el +++ b/etc/themes/manoj-dark-theme.el @@ -700,8 +700,4 @@ manoj-dark (provide-theme 'manoj-dark) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; manoj-dark.el ends here diff --git a/etc/themes/misterioso-theme.el b/etc/themes/misterioso-theme.el index 42e448d28b..6c1eec0f42 100644 --- a/etc/themes/misterioso-theme.el +++ b/etc/themes/misterioso-theme.el @@ -103,8 +103,4 @@ misterioso (provide-theme 'misterioso) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; misterioso-theme.el ends here diff --git a/etc/themes/tango-dark-theme.el b/etc/themes/tango-dark-theme.el index 3b6eeb702e..dae77a5e62 100644 --- a/etc/themes/tango-dark-theme.el +++ b/etc/themes/tango-dark-theme.el @@ -170,8 +170,4 @@ tango-dark (provide-theme 'tango-dark) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; tango-dark-theme.el ends here diff --git a/etc/themes/tango-theme.el b/etc/themes/tango-theme.el index a7a79c04ad..4fe2480bc7 100644 --- a/etc/themes/tango-theme.el +++ b/etc/themes/tango-theme.el @@ -154,8 +154,4 @@ tango (provide-theme 'tango) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; tango-theme.el ends here diff --git a/etc/themes/tsdh-dark-theme.el b/etc/themes/tsdh-dark-theme.el index 287fef8253..c216750cb2 100644 --- a/etc/themes/tsdh-dark-theme.el +++ b/etc/themes/tsdh-dark-theme.el @@ -144,8 +144,4 @@ tsdh-dark (provide-theme 'tsdh-dark) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; tsdh-dark-theme.el ends here diff --git a/etc/themes/tsdh-light-theme.el b/etc/themes/tsdh-light-theme.el index 17a86fdbfe..ce9d1a2c3c 100644 --- a/etc/themes/tsdh-light-theme.el +++ b/etc/themes/tsdh-light-theme.el @@ -106,9 +106,4 @@ tsdh-light (provide-theme 'tsdh-light) - -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; tsdh-light-theme.el ends here diff --git a/etc/themes/wheatgrass-theme.el b/etc/themes/wheatgrass-theme.el index 9585e3aa6e..8d34c28bf4 100644 --- a/etc/themes/wheatgrass-theme.el +++ b/etc/themes/wheatgrass-theme.el @@ -83,8 +83,4 @@ wheatgrass (provide-theme 'wheatgrass) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; wheatgrass-theme.el ends here diff --git a/etc/themes/whiteboard-theme.el b/etc/themes/whiteboard-theme.el index 5db0ddd68d..fe46cb0928 100644 --- a/etc/themes/whiteboard-theme.el +++ b/etc/themes/whiteboard-theme.el @@ -100,8 +100,4 @@ whiteboard (provide-theme 'whiteboard) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; whiteboard-theme.el ends here diff --git a/etc/themes/wombat-theme.el b/etc/themes/wombat-theme.el index 583b8dc3f6..00f29bb9fa 100644 --- a/etc/themes/wombat-theme.el +++ b/etc/themes/wombat-theme.el @@ -102,8 +102,4 @@ wombat (provide-theme 'wombat) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; wombat-theme.el ends here -- 2.17.1 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #4: 0003-Fix-custom-available-themes-file-expansion.patch --] [-- Type: text/x-diff, Size: 6569 bytes --] From 094401d019cd2325e1d9089de19688aa18e7d813 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Wed, 2 May 2018 21:18:24 +0100 Subject: [PATCH 3/8] Fix custom-available-themes file expansion For discussion, see thread starting at https://lists.gnu.org/archive/html/emacs-devel/2018-05/msg00222.html. * lisp/custom.el: (custom-available-themes): Use directory-files instead of performing arbitrary wildcard expansion in file names. (custom-theme--load-path): Document return value. * test/lisp/custom-tests.el: New file. (custom-theme--load-path): New test. --- lisp/custom.el | 24 ++++++----- test/lisp/custom-tests.el | 87 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 10 deletions(-) create mode 100644 test/lisp/custom-tests.el diff --git a/lisp/custom.el b/lisp/custom.el index 1fed5dce53..e076279485 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -1299,19 +1299,23 @@ custom-available-themes loaded, and no effort is made to check that the files contain valid Custom themes. For a list of loaded themes, check the variable `custom-known-themes'." - (let (sym themes) + (let ((suffix "-theme\\.el\\'") + themes) (dolist (dir (custom-theme--load-path)) - (when (file-directory-p dir) - (dolist (file (file-expand-wildcards - (expand-file-name "*-theme.el" dir) t)) - (setq file (file-name-nondirectory file)) - (and (string-match "\\`\\(.+\\)-theme.el\\'" file) - (setq sym (intern (match-string 1 file))) - (custom-theme-name-valid-p sym) - (push sym themes))))) - (nreverse (delete-dups themes)))) + (cl-assert + (file-directory-p dir) t + "Non-existent directory in `custom-theme-load-path' expansion: %s") + (dolist (file (directory-files dir nil suffix)) + (let ((theme (intern (substring file 0 (string-match-p suffix file))))) + (and (custom-theme-name-valid-p theme) + (not (memq theme themes)) + (push theme themes))))) + (nreverse themes))) (defun custom-theme--load-path () + "Expand `custom-theme-load-path' into a list of directories. +Members of `custom-theme-load-path' that either don't exist or +are not directories are omitted from the expansion." (let (lpath) (dolist (f custom-theme-load-path) (cond ((eq f 'custom-theme-directory) diff --git a/test/lisp/custom-tests.el b/test/lisp/custom-tests.el new file mode 100644 index 0000000000..96887f8f5f --- /dev/null +++ b/test/lisp/custom-tests.el @@ -0,0 +1,87 @@ +;;; custom-tests.el --- tests for custom.el -*- lexical-binding: t -*- + +;; Copyright (C) 2018 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs 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. + +;; GNU Emacs 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 program. If not, see <https://www.gnu.org/licenses/>. + +;;; Code: + +(require 'ert) + +(ert-deftest custom-theme--load-path () + "Test `custom-theme--load-path' behavior." + (let ((tmpdir (file-name-as-directory (make-temp-file "custom-tests-" t)))) + (unwind-protect + ;; Create all temporary files under the same deletable parent. + (let ((temporary-file-directory tmpdir)) + ;; Path is empty. + (let ((custom-theme-load-path ())) + (should (null (custom-theme--load-path)))) + + ;; Path comprises non-existent file. + (let* ((name (make-temp-name tmpdir)) + (custom-theme-load-path (list name))) + (should (not (file-exists-p name))) + (should (null (custom-theme--load-path)))) + + ;; Path comprises existing file. + (let* ((file (make-temp-file "file")) + (custom-theme-load-path (list file))) + (should (file-exists-p file)) + (should (not (file-directory-p file))) + (should (null (custom-theme--load-path)))) + + ;; Path comprises existing directory. + (let* ((dir (make-temp-file "dir" t)) + (custom-theme-load-path (list dir))) + (should (file-directory-p dir)) + (should (equal (custom-theme--load-path) custom-theme-load-path))) + + ;; Expand `custom-theme-directory' path element. + (let ((custom-theme-load-path '(custom-theme-directory))) + (let ((custom-theme-directory (make-temp-name tmpdir))) + (should (not (file-exists-p custom-theme-directory))) + (should (null (custom-theme--load-path)))) + (let ((custom-theme-directory (make-temp-file "file"))) + (should (file-exists-p custom-theme-directory)) + (should (not (file-directory-p custom-theme-directory))) + (should (null (custom-theme--load-path)))) + (let ((custom-theme-directory (make-temp-file "dir" t))) + (should (file-directory-p custom-theme-directory)) + (should (equal (custom-theme--load-path) + (list custom-theme-directory))))) + + ;; Expand t path element. + (let ((custom-theme-load-path '(t))) + (let ((data-directory (make-temp-name tmpdir))) + (should (not (file-exists-p data-directory))) + (should (null (custom-theme--load-path)))) + (let ((data-directory tmpdir) + (themedir (expand-file-name "themes" tmpdir))) + (should (not (file-exists-p themedir))) + (should (null (custom-theme--load-path))) + (with-temp-file themedir) + (should (file-exists-p themedir)) + (should (not (file-directory-p themedir))) + (should (null (custom-theme--load-path))) + (delete-file themedir) + (make-directory themedir) + (should (file-directory-p themedir)) + (should (equal (custom-theme--load-path) (list themedir)))))) + (when (file-directory-p tmpdir) + (delete-directory tmpdir t))))) + +;;; custom-tests.el ends here -- 2.17.1 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #5: 0004-lisp-custom.el-Use-lexical-binding.patch --] [-- Type: text/x-diff, Size: 7797 bytes --] From 9cbf1b3f85d86e7660b9eeac8c65b29e404002ba Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Fri, 11 May 2018 16:09:57 +0100 Subject: [PATCH 4/8] * lisp/custom.el: Use lexical-binding Remove duplicate 'Custom Themes' comment heading. (deftheme, custom-declare-theme): Fix advertised calling convention. (custom-enabled-themes): Fix message grammar. --- lisp/custom.el | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/lisp/custom.el b/lisp/custom.el index e076279485..88199a8da5 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -1,4 +1,4 @@ -;;; custom.el --- tools for declaring and initializing options +;;; custom.el --- tools for declaring and initializing options -*- lexical-binding: t -*- ;; ;; Copyright (C) 1996-1997, 1999, 2001-2018 Free Software Foundation, ;; Inc. @@ -150,7 +150,7 @@ custom-declare-variable (put symbol 'force-value nil)) (if (keywordp doc) (error "Doc string is missing")) - (let ((initialize 'custom-initialize-reset) + (let ((initialize #'custom-initialize-reset) (requests nil)) (unless (memq :group args) (custom-add-to-group (custom-current-group) symbol 'custom-variable)) @@ -426,7 +426,7 @@ custom-current-group (defun custom-declare-group (symbol members doc &rest args) "Like `defgroup', but SYMBOL is evaluated as a normal argument." (while members - (apply 'custom-add-to-group symbol (car members)) + (apply #'custom-add-to-group symbol (car members)) (setq members (cdr members))) (when doc ;; This text doesn't get into DOC. @@ -618,11 +618,8 @@ custom-note-var-changed The result is that the change is treated as having been made through Custom." (put variable 'customized-value (list (custom-quote (eval variable))))) -\f -;;; Custom Themes - -;;; Loading files needed to customize a symbol. -;;; This is in custom.el because menu-bar.el needs it for toggle cmds. +;; Loading files needed to customize a symbol. +;; This is in custom.el because menu-bar.el needs it for toggle cmds. (defvar custom-load-recursion nil "Hack to avoid recursive dependencies.") @@ -715,7 +712,7 @@ customize-mark-to-save Return non-nil if the `saved-value' property actually changed." (custom-load-symbol symbol) - (let* ((get (or (get symbol 'custom-get) 'default-value)) + (let* ((get (or (get symbol 'custom-get) #'default-value)) (value (funcall get symbol)) (saved (get symbol 'saved-value)) (standard (get symbol 'standard-value)) @@ -744,7 +741,7 @@ customize-mark-as-set Return non-nil if the `customized-value' property actually changed." (custom-load-symbol symbol) - (let* ((get (or (get symbol 'custom-get) 'default-value)) + (let* ((get (or (get symbol 'custom-get) #'default-value)) (value (funcall get symbol)) (customized (get symbol 'customized-value)) (old (or (get symbol 'saved-value) (get symbol 'standard-value)))) @@ -776,7 +773,7 @@ custom-reevaluate-setting ;; always do the funcall step, even if symbol was not bound before. (or (default-boundp symbol) (eval `(defvar ,symbol nil))) ; reset below, so any value is fine - (funcall (or (get symbol 'custom-set) 'set-default) + (funcall (or (get symbol 'custom-set) #'set-default) symbol (eval (car (or (get symbol 'saved-value) (get symbol 'standard-value)))))) @@ -941,7 +938,7 @@ custom-set-variables REQUEST is a list of features we must require in order to handle SYMBOL properly. COMMENT is a comment string about SYMBOL." - (apply 'custom-theme-set-variables 'user args)) + (apply #'custom-theme-set-variables 'user args)) (defun custom-theme-set-variables (theme &rest args) "Initialize variables for theme THEME according to settings in ARGS. @@ -989,8 +986,8 @@ custom-theme-set-variables set) (when requests (put symbol 'custom-requests requests) - (mapc 'require requests)) - (setq set (or (get symbol 'custom-set) 'custom-set-default)) + (mapc #'require requests)) + (setq set (or (get symbol 'custom-set) #'custom-set-default)) (put symbol 'saved-value (list value)) (put symbol 'saved-variable-comment comment) ;; Allow for errors in the case where the setter has @@ -1086,26 +1083,29 @@ custom--sort-vars-1 ;; they were used to supply keyword-value pairs like `:immediate', ;; `:variable-reset-string', etc. We don't use any of these, so ignore them. -(defmacro deftheme (theme &optional doc &rest ignored) +(defmacro deftheme (theme &optional doc &rest _ignored) "Declare THEME to be a Custom theme. The optional argument DOC is a doc string describing the theme. Any theme `foo' should be defined in a file called `foo-theme.el'; see `custom-make-theme-feature' for more information." - (declare (doc-string 2)) + (declare (doc-string 2) + (advertised-calling-convention (theme &optional doc) "22.1")) (let ((feature (custom-make-theme-feature theme))) ;; It is better not to use backquote in this file, ;; because that makes a bootstrapping problem ;; if you need to recompile all the Lisp files using interpreted code. (list 'custom-declare-theme (list 'quote theme) (list 'quote feature) doc))) -(defun custom-declare-theme (theme feature &optional doc &rest ignored) +(defun custom-declare-theme (theme feature &optional doc &rest _ignored) "Like `deftheme', but THEME is evaluated as a normal argument. FEATURE is the feature this theme provides. Normally, this is a symbol created from THEME by `custom-make-theme-feature'." + (declare (advertised-calling-convention (theme feature &optional doc) "22.1")) (unless (custom-theme-name-valid-p theme) (error "Custom theme cannot be named %S" theme)) - (add-to-list 'custom-known-themes theme) + (unless (memq theme custom-known-themes) + (push theme custom-known-themes)) (put theme 'theme-feature feature) (when doc (put theme 'theme-documentation doc))) @@ -1206,7 +1206,7 @@ load-theme (interactive (list (intern (completing-read "Load custom theme: " - (mapcar 'symbol-name + (mapcar #'symbol-name (custom-available-themes)))) nil nil)) (unless (custom-theme-name-valid-p theme) @@ -1393,9 +1393,9 @@ custom-enabled-themes themes (delq theme themes))))) (enable-theme 'user) (custom-set-default symbol themes) - (if failures - (message "Failed to enable theme: %s" - (mapconcat 'symbol-name failures ", ")))))) + (when failures + (message "Failed to enable theme(s): %s" + (mapconcat #'symbol-name failures ", ")))))) (defsubst custom-theme-enabled-p (theme) "Return non-nil if THEME is enabled." @@ -1407,7 +1407,7 @@ disable-theme (interactive (list (intern (completing-read "Disable custom theme: " - (mapcar 'symbol-name custom-enabled-themes) + (mapcar #'symbol-name custom-enabled-themes) nil t)))) (when (custom-theme-enabled-p theme) (let ((settings (get theme 'theme-settings))) @@ -1473,7 +1473,7 @@ custom-theme-recalc-variable (if (and valspec (or (get variable 'force-value) (default-boundp variable))) - (funcall (or (get variable 'custom-set) 'set-default) variable + (funcall (or (get variable 'custom-set) #'set-default) variable (eval (car valspec)))))) (defun custom-theme-recalc-face (face) @@ -1514,7 +1514,7 @@ custom-reset-variables (VARIABLE IGNORED) This means reset VARIABLE. (The argument IGNORED is ignored)." - (apply 'custom-theme-reset-variables 'user args)) + (apply #'custom-theme-reset-variables 'user args)) ;;; The End. -- 2.17.1 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #6: 0005-lisp-cus-theme.el-Use-lexical-binding.patch --] [-- Type: text/x-diff, Size: 5907 bytes --] From 00688ba60593f1d4e1c3810e0b560f1c3cbe1ac7 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Fri, 11 May 2018 15:35:09 +0100 Subject: [PATCH 5/8] * lisp/cus-theme.el: Use lexical-binding --- lisp/cus-theme.el | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/lisp/cus-theme.el b/lisp/cus-theme.el index e5e787771b..53389956ad 100644 --- a/lisp/cus-theme.el +++ b/lisp/cus-theme.el @@ -1,4 +1,4 @@ -;;; cus-theme.el -- custom theme creation user interface +;;; cus-theme.el -- custom theme creation user interface -*- lexical-binding: t -*- ;; ;; Copyright (C) 2001-2018 Free Software Foundation, Inc. ;; @@ -47,7 +47,7 @@ custom-new-theme-mode Do not call this mode function yourself. It is meant for internal use." (use-local-map custom-new-theme-mode-map) (custom--initialize-widget-variables) - (set (make-local-variable 'revert-buffer-function) 'custom-theme-revert)) + (set (make-local-variable 'revert-buffer-function) #'custom-theme-revert)) (put 'custom-new-theme-mode 'mode-class 'special) (defvar custom-theme-name nil) @@ -118,13 +118,13 @@ customize-create-theme :tag " Visit Theme " :help-echo "Insert the settings of a pre-defined theme." :action (lambda (_widget &optional _event) - (call-interactively 'custom-theme-visit-theme))) + (call-interactively #'custom-theme-visit-theme))) (widget-insert " ") (widget-create 'push-button :tag " Merge Theme " :help-echo "Merge in the settings of a pre-defined theme." :action (lambda (_widget &optional _event) - (call-interactively 'custom-theme-merge-theme))) + (call-interactively #'custom-theme-merge-theme))) (widget-insert " ") (widget-create 'push-button :tag " Revert " @@ -142,7 +142,7 @@ customize-create-theme (widget-create 'text :value (format-time-string "Created %Y-%m-%d."))) (widget-create 'push-button - :notify (function custom-theme-write) + :notify #'custom-theme-write " Save Theme ") (when (eq theme 'user) (setq custom-theme--migrate-settings t) @@ -188,7 +188,7 @@ customize-create-theme :mouse-face 'highlight :pressed-face 'highlight :action (lambda (_widget &optional _event) - (call-interactively 'custom-theme-add-face))) + (call-interactively #'custom-theme-add-face))) ;; If THEME is non-nil, insert all of that theme's variables. (widget-insert "\n\n Theme variables:\n ") @@ -207,7 +207,7 @@ customize-create-theme :mouse-face 'highlight :pressed-face 'highlight :action (lambda (_widget &optional _event) - (call-interactively 'custom-theme-add-variable))) + (call-interactively #'custom-theme-add-variable))) (widget-insert ?\n) (widget-setup) (goto-char (point-min)) @@ -254,7 +254,7 @@ custom-theme-add-var-1 :tag (custom-unlispify-tag-name symbol) :value symbol :shown-value (list val) - :notify 'ignore + :notify #'ignore :custom-level 0 :custom-state 'hidden :custom-style 'simple)) @@ -313,7 +313,7 @@ custom-theme-visit-theme (interactive (list (intern (completing-read "Find custom theme: " - (mapcar 'symbol-name + (mapcar #'symbol-name (custom-available-themes)))))) (unless (custom-theme-name-valid-p theme) (error "No valid theme named `%s'" theme)) @@ -328,7 +328,7 @@ custom-theme-merge-theme (interactive (list (intern (completing-read "Merge custom theme: " - (mapcar 'symbol-name + (mapcar #'symbol-name (custom-available-themes)))))) (unless (eq theme 'user) (unless (custom-theme-name-valid-p theme) @@ -343,8 +343,8 @@ custom-theme-merge-theme (memq name '(custom-enabled-themes custom-safe-themes))) (funcall (if option - 'custom-theme-add-variable - 'custom-theme-add-face) + #'custom-theme-add-variable + #'custom-theme-add-face) name value))))) theme) @@ -475,7 +475,7 @@ describe-theme (interactive (list (intern (completing-read "Describe custom theme: " - (mapcar 'symbol-name + (mapcar #'symbol-name (custom-available-themes)))))) (unless (custom-theme-name-valid-p theme) (error "Invalid theme name `%s'" theme)) @@ -616,11 +616,11 @@ customize-themes (widget-create 'push-button :tag " Save Theme Settings " :help-echo "Save the selected themes for future sessions." - :action 'custom-theme-save) + :action #'custom-theme-save) (widget-insert ?\n) (widget-create 'checkbox :value custom-theme-allow-multiple-selections - :action 'custom-theme-selections-toggle) + :action #'custom-theme-selections-toggle) (widget-insert (propertize " Select more than one theme at a time" 'face '(variable-pitch (:height 0.9)))) @@ -632,13 +632,13 @@ customize-themes :value (custom-theme-enabled-p theme) :theme-name theme :help-echo help-echo - :action 'custom-theme-checkbox-toggle)) + :action #'custom-theme-checkbox-toggle)) (push (cons theme widget) custom--listed-themes) (widget-create-child-and-convert widget 'push-button :button-face-get 'ignore :mouse-face-get 'ignore :value (format " %s" theme) - :action 'widget-parent-action + :action #'widget-parent-action :help-echo help-echo) (widget-insert " -- " (propertize (custom-theme-summary theme) -- 2.17.1 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #7: 0006-Minor-custom.el-simplifications.patch --] [-- Type: text/x-diff, Size: 7892 bytes --] From 4df55309a51c4b8f7f421f4b080db9b64182ee34 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Thu, 31 May 2018 18:37:02 +0100 Subject: [PATCH 6/8] Minor custom.el simplifications * lisp/custom.el (custom-quote): Duplicate macroexp-quote. (custom-load-symbol, customize-mark-to-save, customize-mark-as-set) (custom-theme-name-valid-p, enable-theme, custom-enabled-themes) (disable-theme): Simplify logic. --- lisp/custom.el | 103 ++++++++++++++++++++++--------------------------- 1 file changed, 46 insertions(+), 57 deletions(-) diff --git a/lisp/custom.el b/lisp/custom.el index 88199a8da5..f08a8e9c3e 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -630,14 +630,12 @@ custom-load-symbol (let ((custom-load-recursion t)) ;; Load these files if not already done, ;; to make sure we know all the dependencies of SYMBOL. - (condition-case nil - (require 'cus-load) - (error nil)) - (condition-case nil - (require 'cus-start) - (error nil)) + (ignore-errors + (require 'cus-load)) + (ignore-errors + (require 'cus-start)) (dolist (load (get symbol 'custom-loads)) - (cond ((symbolp load) (condition-case nil (require load) (error nil))) + (cond ((symbolp load) (ignore-errors (require load))) ;; This is subsumed by the test below, but it's much faster. ((assoc load load-history)) ;; This was just (assoc (locate-library load) load-history) @@ -655,7 +653,7 @@ custom-load-symbol ;; We are still loading it when we call this, ;; and it is not in load-history yet. ((equal load "cus-edit")) - (t (condition-case nil (load load) (error nil)))))))) + (t (ignore-errors (load load)))))))) \f (defvar custom-local-buffer nil "Non-nil, in a Customization buffer, means customize a specific buffer. @@ -688,16 +686,12 @@ custom-set-minor-mode (defun custom-quote (sexp) "Quote SEXP if it is not self quoting." - (if (or (memq sexp '(t nil)) - (keywordp sexp) - (and (listp sexp) - (memq (car sexp) '(lambda))) - (stringp sexp) - (numberp sexp) - (vectorp sexp) -;;; (and (fboundp 'characterp) -;;; (characterp sexp)) - ) + ;; Can't use `macroexp-quote' because it is loaded after `custom.el' + ;; during bootstrap. See `loadup.el'. + (if (and (not (consp sexp)) + (or (keywordp sexp) + (not (symbolp sexp)) + (booleanp sexp))) sexp (list 'quote sexp))) @@ -718,12 +712,10 @@ customize-mark-to-save (standard (get symbol 'standard-value)) (comment (get symbol 'customized-variable-comment))) ;; Save default value if different from standard value. - (if (or (null standard) - (not (equal value (condition-case nil - (eval (car standard)) - (error nil))))) - (put symbol 'saved-value (list (custom-quote value))) - (put symbol 'saved-value nil)) + (put symbol 'saved-value + (unless (and standard + (equal value (ignore-errors (eval (car standard))))) + (list (custom-quote value)))) ;; Clear customized information (set, but not saved). (put symbol 'customized-value nil) ;; Save any comment that might have been set. @@ -747,9 +739,8 @@ customize-mark-as-set (old (or (get symbol 'saved-value) (get symbol 'standard-value)))) ;; Mark default value as set if different from old value. (if (not (and old - (equal value (condition-case nil - (eval (car old)) - (error nil))))) + (equal value (ignore-errors + (eval (car old)))))) (progn (put symbol 'customized-value (list (custom-quote value))) (custom-push-theme 'theme-value symbol 'user 'set (custom-quote value))) @@ -1284,11 +1275,9 @@ custom-theme-load-confirm (defun custom-theme-name-valid-p (name) "Return t if NAME is a valid name for a Custom theme, nil otherwise. NAME should be a symbol." - (and (symbolp name) - name - (not (or (zerop (length (symbol-name name))) - (eq name 'user) - (eq name 'changed))))) + (and (not (memq name '(nil user changed))) + (symbolp name) + (not (string= "" (symbol-name name))))) (defun custom-available-themes () "Return a list of Custom themes available for loading. @@ -1338,8 +1327,8 @@ enable-theme (completing-read "Enable custom theme: " obarray (lambda (sym) (get sym 'theme-settings)) t)))) - (if (not (custom-theme-p theme)) - (error "Undefined Custom theme %s" theme)) + (unless (custom-theme-p theme) + (error "Undefined Custom theme %s" theme)) (let ((settings (get theme 'theme-settings))) ;; Loop through theme settings, recalculating vars/faces. (dolist (s settings) @@ -1379,18 +1368,18 @@ custom-enabled-themes (let (failures) (setq themes (delq 'user (delete-dups themes))) ;; Disable all themes not in THEMES. - (if (boundp symbol) - (dolist (theme (symbol-value symbol)) - (if (not (memq theme themes)) - (disable-theme theme)))) + (dolist (theme (and (boundp symbol) + (symbol-value symbol))) + (unless (memq theme themes) + (disable-theme theme))) ;; Call `enable-theme' or `load-theme' on each of THEMES. (dolist (theme (reverse themes)) (condition-case nil (if (custom-theme-p theme) (enable-theme theme) (load-theme theme)) - (error (setq failures (cons theme failures) - themes (delq theme themes))))) + (error (push theme failures) + (setq themes (delq theme themes))))) (enable-theme 'user) (custom-set-default symbol themes) (when failures @@ -1423,23 +1412,23 @@ disable-theme ;; If the face spec specified by this theme is in the ;; saved-face property, reset that property. (when (equal (nth 3 s) (get symbol 'saved-face)) - (put symbol 'saved-face (and val (cadr (car val))))))))) - ;; Recompute faces on all frames. - (dolist (frame (frame-list)) - ;; We must reset the fg and bg color frame parameters, or - ;; `face-set-after-frame-default' will use the existing - ;; parameters, which could be from the disabled theme. - (set-frame-parameter frame 'background-color - (custom--frame-color-default - frame :background "background" "Background" - "unspecified-bg" "white")) - (set-frame-parameter frame 'foreground-color - (custom--frame-color-default - frame :foreground "foreground" "Foreground" - "unspecified-fg" "black")) - (face-set-after-frame-default frame)) - (setq custom-enabled-themes - (delq theme custom-enabled-themes))))) + (put symbol 'saved-face (cadar val)))))))) + ;; Recompute faces on all frames. + (dolist (frame (frame-list)) + ;; We must reset the fg and bg color frame parameters, or + ;; `face-set-after-frame-default' will use the existing + ;; parameters, which could be from the disabled theme. + (set-frame-parameter frame 'background-color + (custom--frame-color-default + frame :background "background" "Background" + "unspecified-bg" "white")) + (set-frame-parameter frame 'foreground-color + (custom--frame-color-default + frame :foreground "foreground" "Foreground" + "unspecified-fg" "black")) + (face-set-after-frame-default frame)) + (setq custom-enabled-themes + (delq theme custom-enabled-themes)))) ;; Only used if window-system not null. (declare-function x-get-resource "frame.c" -- 2.17.1 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #8: 0007-Minor-cus-theme.el-simplifications.patch --] [-- Type: text/x-diff, Size: 3932 bytes --] From e37a3313a4e78161840d5009b65805ff7ba2a514 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Thu, 10 May 2018 03:08:10 +0100 Subject: [PATCH 7/8] Minor cus-theme.el simplifications * lisp/cus-theme.el (custom-new-theme-mode, customize-themes) (custom-theme-choose-mode): Use setq-local. (customize-create-theme): Ditto. Use delete-all-overlays. (describe-theme-1, custom-theme-summary): Simplify logic. --- lisp/cus-theme.el | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/lisp/cus-theme.el b/lisp/cus-theme.el index 53389956ad..995c55b2b2 100644 --- a/lisp/cus-theme.el +++ b/lisp/cus-theme.el @@ -47,7 +47,7 @@ custom-new-theme-mode Do not call this mode function yourself. It is meant for internal use." (use-local-map custom-new-theme-mode-map) (custom--initialize-widget-variables) - (set (make-local-variable 'revert-buffer-function) #'custom-theme-revert)) + (setq-local revert-buffer-function #'custom-theme-revert)) (put 'custom-new-theme-mode 'mode-class 'special) (defvar custom-theme-name nil) @@ -93,15 +93,14 @@ customize-create-theme (switch-to-buffer (get-buffer-create (or buffer "*Custom Theme*"))) (let ((inhibit-read-only t)) (erase-buffer) - (dolist (ov (overlays-in (point-min) (point-max))) - (delete-overlay ov))) + (delete-all-overlays)) (custom-new-theme-mode) (make-local-variable 'custom-theme-name) - (set (make-local-variable 'custom-theme--save-name) theme) - (set (make-local-variable 'custom-theme-faces) nil) - (set (make-local-variable 'custom-theme-variables) nil) - (set (make-local-variable 'custom-theme-description) "") - (set (make-local-variable 'custom-theme--migrate-settings) nil) + (setq-local custom-theme--save-name theme) + (setq-local custom-theme-faces nil) + (setq-local custom-theme-variables nil) + (setq-local custom-theme-description "") + (setq-local custom-theme--migrate-settings nil) (make-local-variable 'custom-theme-insert-face-marker) (make-local-variable 'custom-theme-insert-variable-marker) (make-local-variable 'custom-theme--listed-faces) @@ -513,8 +512,7 @@ describe-theme-1 (condition-case nil (read (current-buffer)) (end-of-file nil))))) - (and sexp (listp sexp) - (eq (car sexp) 'deftheme) + (and (eq (car-safe sexp) 'deftheme) (setq doc (nth 2 sexp))))))) (princ "\n\nDocumentation:\n") (princ (if (stringp doc) @@ -552,10 +550,10 @@ custom-theme-choose-mode Do not call this mode function yourself. It is meant for internal use." (use-local-map custom-theme-choose-mode-map) (custom--initialize-widget-variables) - (set (make-local-variable 'revert-buffer-function) - (lambda (_ignore-auto noconfirm) - (when (or noconfirm (y-or-n-p "Discard current choices? ")) - (customize-themes (current-buffer)))))) + (setq-local revert-buffer-function + (lambda (_ignore-auto noconfirm) + (when (or noconfirm (y-or-n-p "Discard current choices? ")) + (customize-themes (current-buffer)))))) (put 'custom-theme-choose-mode 'mode-class 'special) ;;;###autoload @@ -568,7 +566,7 @@ customize-themes (let ((inhibit-read-only t)) (erase-buffer)) (custom-theme-choose-mode) - (set (make-local-variable 'custom--listed-themes) nil) + (setq-local custom--listed-themes nil) (make-local-variable 'custom-theme-allow-multiple-selections) (and (null custom-theme-allow-multiple-selections) (> (length custom-enabled-themes) 1) @@ -662,8 +660,7 @@ custom-theme-summary (condition-case nil (read (current-buffer)) (end-of-file nil))))) - (and sexp (listp sexp) - (eq (car sexp) 'deftheme) + (and (eq (car-safe sexp) 'deftheme) (setq doc (nth 2 sexp)))))))) (cond ((null doc) "(no documentation available)") -- 2.17.1 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #9: 0008-Tweak-subr-x.el-substring-functions.patch --] [-- Type: text/x-diff, Size: 4709 bytes --] From cf179936f1245f6f2b98385fd969abf78e8a15cf Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Fri, 1 Jun 2018 21:58:10 +0100 Subject: [PATCH 8/8] Tweak subr-x.el substring functions * lisp/emacs-lisp/subr-x.el (string-join): #'-quote function symbol. (string-trim-left, string-trim-right): Make better use of substring for minor speedup. * test/lisp/emacs-lisp/subr-x-tests.el (subr-x-test-string-trim-left, subr-x-test-string-trim-right) (subr-x-test-string-remove-prefix) (subr-x-test-string-remove-suffix): New tests. --- lisp/emacs-lisp/subr-x.el | 12 +++---- test/lisp/emacs-lisp/subr-x-tests.el | 47 ++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el index 7fab9083e8..eb3ec85ecc 100644 --- a/lisp/emacs-lisp/subr-x.el +++ b/lisp/emacs-lisp/subr-x.el @@ -211,7 +211,7 @@ string-empty-p (defsubst string-join (strings &optional separator) "Join all STRINGS using SEPARATOR." - (mapconcat 'identity strings separator)) + (mapconcat #'identity strings separator)) (define-obsolete-function-alias 'string-reverse 'reverse "25.1") @@ -219,17 +219,17 @@ string-trim-left "Trim STRING of leading string matching REGEXP. REGEXP defaults to \"[ \\t\\n\\r]+\"." - (if (string-match (concat "\\`\\(?:" (or regexp "[ \t\n\r]+")"\\)") string) - (replace-match "" t t string) + (if (string-match (concat "\\`\\(?:" (or regexp "[ \t\n\r]+") "\\)") string) + (substring string (match-end 0)) string)) (defsubst string-trim-right (string &optional regexp) "Trim STRING of trailing string matching REGEXP. REGEXP defaults to \"[ \\t\\n\\r]+\"." - (if (string-match (concat "\\(?:" (or regexp "[ \t\n\r]+") "\\)\\'") string) - (replace-match "" t t string) - string)) + (let ((i (string-match-p (concat "\\(?:" (or regexp "[ \t\n\r]+") "\\)\\'") + string))) + (if i (substring string 0 i) string))) (defsubst string-trim (string &optional trim-left trim-right) "Trim STRING of leading and trailing strings matching TRIM-LEFT and TRIM-RIGHT. diff --git a/test/lisp/emacs-lisp/subr-x-tests.el b/test/lisp/emacs-lisp/subr-x-tests.el index f7f0ef384f..81467bab2d 100644 --- a/test/lisp/emacs-lisp/subr-x-tests.el +++ b/test/lisp/emacs-lisp/subr-x-tests.el @@ -532,6 +532,53 @@ (format "abs sum is: %s")) "abs sum is: 15"))) +\f +;; Substring tests + +(ert-deftest subr-x-test-string-trim-left () + "Test `string-trim-left' behavior." + (should (equal (string-trim-left "") "")) + (should (equal (string-trim-left " \t\n\r") "")) + (should (equal (string-trim-left " \t\n\ra") "a")) + (should (equal (string-trim-left "a \t\n\r") "a \t\n\r")) + (should (equal (string-trim-left "" "") "")) + (should (equal (string-trim-left "a" "") "a")) + (should (equal (string-trim-left "aa" "a*") "")) + (should (equal (string-trim-left "ba" "a*") "ba")) + (should (equal (string-trim-left "aa" "a*?") "aa")) + (should (equal (string-trim-left "aa" "a+?") "a"))) + +(ert-deftest subr-x-test-string-trim-right () + "Test `string-trim-right' behavior." + (should (equal (string-trim-right "") "")) + (should (equal (string-trim-right " \t\n\r") "")) + (should (equal (string-trim-right " \t\n\ra") " \t\n\ra")) + (should (equal (string-trim-right "a \t\n\r") "a")) + (should (equal (string-trim-right "" "") "")) + (should (equal (string-trim-right "a" "") "a")) + (should (equal (string-trim-right "aa" "a*") "")) + (should (equal (string-trim-right "ab" "a*") "ab")) + (should (equal (string-trim-right "aa" "a*?") ""))) + +(ert-deftest subr-x-test-string-remove-prefix () + "Test `string-remove-prefix' behavior." + (should (equal (string-remove-prefix "" "") "")) + (should (equal (string-remove-prefix "" "a") "a")) + (should (equal (string-remove-prefix "a" "") "")) + (should (equal (string-remove-prefix "a" "b") "b")) + (should (equal (string-remove-prefix "a" "a") "")) + (should (equal (string-remove-prefix "a" "aa") "a")) + (should (equal (string-remove-prefix "a" "ab") "b"))) + +(ert-deftest subr-x-test-string-remove-suffix () + "Test `string-remove-suffix' behavior." + (should (equal (string-remove-suffix "" "") "")) + (should (equal (string-remove-suffix "" "a") "a")) + (should (equal (string-remove-suffix "a" "") "")) + (should (equal (string-remove-suffix "a" "b") "b")) + (should (equal (string-remove-suffix "a" "a") "")) + (should (equal (string-remove-suffix "a" "aa") "a")) + (should (equal (string-remove-suffix "a" "ba") "b"))) (provide 'subr-x-tests) ;;; subr-x-tests.el ends here -- 2.17.1 ^ permalink raw reply related [flat|nested] 33+ messages in thread
* Re: Byte-compilation of custom themes 2018-06-02 19:32 ` Eli Zaretskii 2018-06-02 20:02 ` Basil L. Contovounesios @ 2018-06-03 3:52 ` Stefan Monnier 2018-06-03 11:21 ` Basil L. Contovounesios 1 sibling, 1 reply; 33+ messages in thread From: Stefan Monnier @ 2018-06-03 3:52 UTC (permalink / raw To: emacs-devel > I meant featurep, but since cl-assert is autoloaded, that shouldn't be AFAICT it's not autoloaded. I think the confusing comes from help-fns.el which does (require 'cl-lib), so if you do `C-h f cl-assert RET` it will indeed tell you it's autoloaded, but it's just because `C-h f` ended up requiring cl-lib. Stefan ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Byte-compilation of custom themes 2018-06-03 3:52 ` Stefan Monnier @ 2018-06-03 11:21 ` Basil L. Contovounesios 2018-06-03 15:11 ` Eli Zaretskii 0 siblings, 1 reply; 33+ messages in thread From: Basil L. Contovounesios @ 2018-06-03 11:21 UTC (permalink / raw To: Stefan Monnier; +Cc: Eli Zaretskii, emacs-devel [-- Attachment #1: Type: text/plain, Size: 926 bytes --] Stefan Monnier <monnier@iro.umontreal.ca> writes: >> I meant featurep, but since cl-assert is autoloaded, that shouldn't be > > AFAICT it's not autoloaded. You're right, emacs -Q followed by (fboundp 'cl-assert) returns nil. > I think the confusing comes from help-fns.el which does (require > 'cl-lib), so if you do `C-h f cl-assert RET` it will indeed tell you > it's autoloaded, but it's just because `C-h f` ended up requiring > cl-lib. No, the confusion comes from looking at the source of cl-macs.el, in which cl-assert is given an ;;;###autoload cookie. I see now that there are some comments in cl-lib.el that suggest loading cl-loaddefs.el involves some trickery, so I guess I don't get to eat the cake here. In that case, I don't see how Eli's suggestion to predicate the cl-assert call on (featurep 'cl-lib) will help, as feauturep is not going to load the library for us. Do we want the following instead? [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: assert.diff --] [-- Type: text/x-diff, Size: 857 bytes --] diff --git a/lisp/custom.el b/lisp/custom.el index 076790b661..e55c9db1ac 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -1288,10 +1288,13 @@ custom-available-themes loaded, and no effort is made to check that the files contain valid Custom themes. For a list of loaded themes, check the variable `custom-known-themes'." + (eval-when-compile (require 'cl-lib)) (let ((suffix "-theme\\.el\\'") themes) (dolist (dir (custom-theme--load-path)) - ;; `custom-theme--load-path' promises DIR exists and is a directory. + (cl-assert + (file-directory-p dir) t + "Non-existent directory in `custom-theme-load-path' expansion: %s") (dolist (file (directory-files dir nil suffix)) (let ((theme (intern (substring file 0 (string-match-p suffix file))))) (and (custom-theme-name-valid-p theme) [-- Attachment #3: Type: text/plain, Size: 11 bytes --] -- Basil ^ permalink raw reply related [flat|nested] 33+ messages in thread
* Re: Byte-compilation of custom themes 2018-06-03 11:21 ` Basil L. Contovounesios @ 2018-06-03 15:11 ` Eli Zaretskii 2018-06-03 16:08 ` Basil L. Contovounesios 0 siblings, 1 reply; 33+ messages in thread From: Eli Zaretskii @ 2018-06-03 15:11 UTC (permalink / raw To: Basil L. Contovounesios; +Cc: monnier, emacs-devel > From: "Basil L. Contovounesios" <contovob@tcd.ie> > Cc: <emacs-devel@gnu.org>, Eli Zaretskii <eliz@gnu.org> > Date: Sun, 03 Jun 2018 12:21:07 +0100 > > You're right, emacs -Q followed by (fboundp 'cl-assert) returns nil. > > > I think the confusing comes from help-fns.el which does (require > > 'cl-lib), so if you do `C-h f cl-assert RET` it will indeed tell you > > it's autoloaded, but it's just because `C-h f` ended up requiring > > cl-lib. > > No, the confusion comes from looking at the source of cl-macs.el, in > which cl-assert is given an ;;;###autoload cookie. I see now that there > are some comments in cl-lib.el that suggest loading cl-loaddefs.el > involves some trickery, so I guess I don't get to eat the cake here. > > In that case, I don't see how Eli's suggestion to predicate the > cl-assert call on (featurep 'cl-lib) will help, as feauturep is not > going to load the library for us. ??? I meant the following obvious trick: (if (featurep 'cl-lib) (cl-assert ....)) Am I missing something? ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Byte-compilation of custom themes 2018-06-03 15:11 ` Eli Zaretskii @ 2018-06-03 16:08 ` Basil L. Contovounesios 2018-06-03 16:16 ` Eli Zaretskii 0 siblings, 1 reply; 33+ messages in thread From: Basil L. Contovounesios @ 2018-06-03 16:08 UTC (permalink / raw To: Eli Zaretskii; +Cc: monnier, emacs-devel Eli Zaretskii <eliz@gnu.org> writes: >> From: "Basil L. Contovounesios" <contovob@tcd.ie> >> Cc: <emacs-devel@gnu.org>, Eli Zaretskii <eliz@gnu.org> >> Date: Sun, 03 Jun 2018 12:21:07 +0100 >> >> You're right, emacs -Q followed by (fboundp 'cl-assert) returns nil. >> >> > I think the confusing comes from help-fns.el which does (require >> > 'cl-lib), so if you do `C-h f cl-assert RET` it will indeed tell you >> > it's autoloaded, but it's just because `C-h f` ended up requiring >> > cl-lib. >> >> No, the confusion comes from looking at the source of cl-macs.el, in >> which cl-assert is given an ;;;###autoload cookie. I see now that there >> are some comments in cl-lib.el that suggest loading cl-loaddefs.el >> involves some trickery, so I guess I don't get to eat the cake here. >> >> In that case, I don't see how Eli's suggestion to predicate the >> cl-assert call on (featurep 'cl-lib) will help, as feauturep is not >> going to load the library for us. > > ??? I meant the following obvious trick: > > (if (featurep 'cl-lib) > (cl-assert ....)) > > Am I missing something? I understood what you meant, but not what this is supposed to do or protect against. You see, 'make bootstrap' fails not when there is an ungaurded call to cl-assert in custom-available-themes, but when there is a top-level (require 'cl-lib) in custom.el. So, if we can't load cl-lib at the top-level of custom.el, and we don't load cl-lib in custom-available-themes, then the featurep check says "only call cl-assert if some other library has already loaded cl-lib for us", which doesn't make sense to me. What is the benefit of conditionally calling an assertion at runtime? Why wouldn't we want the assertion to be exercised every time custom-available-themes is called? Just to be clear, including any one of the following three top-level forms in custom.el breaks 'make bootstrap', irrespective of the NOERROR argument passed to require, and even when there is no subsequent mention of cl-assert or any other cl-lib feature in custom.el: (require 'cl-lib) (eval-when-compile (require 'cl-lib)) (when t (require 'cl-lib)) In all three cases, 'make bootstrap' reports the following: Loading custom (source)... Warning: Unknown defun property ‘gv-setter’ in cl-fifth Warning: Unknown defun property ‘gv-setter’ in cl-sixth Warning: Unknown defun property ‘gv-setter’ in cl-seventh Warning: Unknown defun property ‘gv-setter’ in cl-eighth Warning: Unknown defun property ‘gv-setter’ in cl-ninth Warning: Unknown defun property ‘gv-setter’ in cl-tenth Symbol’s function definition is void: gv-define-simple-setter Makefile:745: recipe for target 'bootstrap-emacs' failed I hope I've clarified the source of my confusion and apologise if I'm missing something obvious. Thanks, -- Basil ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Byte-compilation of custom themes 2018-06-03 16:08 ` Basil L. Contovounesios @ 2018-06-03 16:16 ` Eli Zaretskii 2018-06-03 17:48 ` Basil L. Contovounesios 0 siblings, 1 reply; 33+ messages in thread From: Eli Zaretskii @ 2018-06-03 16:16 UTC (permalink / raw To: Basil L. Contovounesios; +Cc: monnier, emacs-devel > From: "Basil L. Contovounesios" <contovob@tcd.ie> > Cc: <monnier@iro.umontreal.ca>, <emacs-devel@gnu.org> > Date: Sun, 03 Jun 2018 17:08:22 +0100 > > So, if we can't load cl-lib at the top-level of custom.el, and we don't > load cl-lib in custom-available-themes, then the featurep check says > "only call cl-assert if some other library has already loaded cl-lib for > us", which doesn't make sense to me. What is the benefit of > conditionally calling an assertion at runtime? In most sessions cl-lib is loaded pretty close to startup, so the problem doesn't exist in practice, IMO. > Why wouldn't we want the assertion to be exercised every time > custom-available-themes is called? Because it's complicated, and I don't see any reason to justify that complication? But this is not a string opinion, so we could just drop the issue and move on. Thanks. > Just to be clear, including any one of the following three top-level > forms in custom.el breaks 'make bootstrap', irrespective of the NOERROR > argument passed to require, and even when there is no subsequent mention > of cl-assert or any other cl-lib feature in custom.el: > > (require 'cl-lib) > (eval-when-compile (require 'cl-lib)) > (when t (require 'cl-lib)) > > In all three cases, 'make bootstrap' reports the following: > > Loading custom (source)... > Warning: Unknown defun property ‘gv-setter’ in cl-fifth > Warning: Unknown defun property ‘gv-setter’ in cl-sixth > Warning: Unknown defun property ‘gv-setter’ in cl-seventh > Warning: Unknown defun property ‘gv-setter’ in cl-eighth > Warning: Unknown defun property ‘gv-setter’ in cl-ninth > Warning: Unknown defun property ‘gv-setter’ in cl-tenth > Symbol’s function definition is void: gv-define-simple-setter > Makefile:745: recipe for target 'bootstrap-emacs' failed Any reason you require cl-lib and not cl-macs? ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Byte-compilation of custom themes 2018-06-03 16:16 ` Eli Zaretskii @ 2018-06-03 17:48 ` Basil L. Contovounesios 2018-06-03 20:22 ` Stefan Monnier 0 siblings, 1 reply; 33+ messages in thread From: Basil L. Contovounesios @ 2018-06-03 17:48 UTC (permalink / raw To: Eli Zaretskii; +Cc: monnier, emacs-devel [-- Attachment #1: Type: text/plain, Size: 2767 bytes --] Eli Zaretskii <eliz@gnu.org> writes: >> From: "Basil L. Contovounesios" <contovob@tcd.ie> >> Cc: <monnier@iro.umontreal.ca>, <emacs-devel@gnu.org> >> Date: Sun, 03 Jun 2018 17:08:22 +0100 >> >> So, if we can't load cl-lib at the top-level of custom.el, and we don't >> load cl-lib in custom-available-themes, then the featurep check says >> "only call cl-assert if some other library has already loaded cl-lib for >> us", which doesn't make sense to me. What is the benefit of >> conditionally calling an assertion at runtime? > > In most sessions cl-lib is loaded pretty close to startup, so the > problem doesn't exist in practice, IMO. > >> Why wouldn't we want the assertion to be exercised every time >> custom-available-themes is called? > > Because it's complicated, and I don't see any reason to justify that > complication? > > But this is not a string opinion, so we could just drop the issue and > move on. Fair enough, though it's looking like the simplest solution is to keep the original (when (file-directory-p dir) ...) check and avoid cl-lib altogether. Anyway, I have updated the relevant patch according to your suggestion (the fboundp check is effectively equivalent to the featurep one, but additionally silences the byte-compiler) and reattach the set of patches; let me know if there are any outstanding issues with them. >> Just to be clear, including any one of the following three top-level >> forms in custom.el breaks 'make bootstrap', irrespective of the NOERROR >> argument passed to require, and even when there is no subsequent mention >> of cl-assert or any other cl-lib feature in custom.el: >> >> (require 'cl-lib) >> (eval-when-compile (require 'cl-lib)) >> (when t (require 'cl-lib)) >> >> In all three cases, 'make bootstrap' reports the following: >> >> Loading custom (source)... >> Warning: Unknown defun property ‘gv-setter’ in cl-fifth >> Warning: Unknown defun property ‘gv-setter’ in cl-sixth >> Warning: Unknown defun property ‘gv-setter’ in cl-seventh >> Warning: Unknown defun property ‘gv-setter’ in cl-eighth >> Warning: Unknown defun property ‘gv-setter’ in cl-ninth >> Warning: Unknown defun property ‘gv-setter’ in cl-tenth >> Symbol’s function definition is void: gv-define-simple-setter >> Makefile:745: recipe for target 'bootstrap-emacs' failed > > Any reason you require cl-lib and not cl-macs? I was following the suggestion of (info "(cl) Usage"), which implies that the internal organisation of cl-lib is a bit of an implementation detail. I realise now that this suggestion is aimed more at external packages, not Emacs core, though. Bootstrap fails either way. Thanks for indulging me, -- Basil [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: 0001-Improve-loading-of-byte-compiled-custom-themes.patch --] [-- Type: text/x-diff, Size: 4290 bytes --] From ca42eaa51a0e3b2316b9783eb77cab316530c231 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Wed, 9 May 2018 22:20:47 +0100 Subject: [PATCH 1/8] Improve loading of byte-compiled custom themes * lisp/custom.el (load-theme): Load byte-compiled file of safe themes when available. https://lists.gnu.org/archive/html/emacs-devel/2018-01/msg00614.html https://lists.gnu.org/archive/html/emacs-devel/2018-02/msg00060.html --- lisp/custom.el | 78 ++++++++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 37 deletions(-) diff --git a/lisp/custom.el b/lisp/custom.el index b7539685a8..1fed5dce53 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -1221,43 +1221,47 @@ load-theme (put theme 'theme-settings nil) (put theme 'theme-feature nil) (put theme 'theme-documentation nil)) - (let ((fn (locate-file (concat (symbol-name theme) "-theme.el") - (custom-theme--load-path) - '("" "c")))) - (unless fn - (error "Unable to find theme file for `%s'" theme)) - (with-temp-buffer - (insert-file-contents fn) - ;; Check file safety with `custom-safe-themes', prompting the - ;; user if necessary. - (when (or no-confirm - (eq custom-safe-themes t) - (and (memq 'default custom-safe-themes) - (equal (file-name-directory fn) - (expand-file-name "themes/" data-directory))) - (let ((hash (secure-hash 'sha256 (current-buffer)))) - (or (member hash custom-safe-themes) - (custom-theme-load-confirm hash)))) - (let ((custom--inhibit-theme-enable t) - (buffer-file-name fn)) ;For load-history. - (eval-buffer)) - ;; Optimization: if the theme changes the `default' face, put that - ;; entry first. This avoids some `frame-set-background-mode' rigmarole - ;; by assigning the new background immediately. - (let* ((settings (get theme 'theme-settings)) - (tail settings) - found) - (while (and tail (not found)) - (and (eq (nth 0 (car tail)) 'theme-face) - (eq (nth 1 (car tail)) 'default) - (setq found (car tail))) - (setq tail (cdr tail))) - (if found - (put theme 'theme-settings (cons found (delq found settings))))) - ;; Finally, enable the theme. - (unless no-enable - (enable-theme theme)) - t)))) + (let ((file (locate-file (concat (symbol-name theme) "-theme.el") + (custom-theme--load-path) + '("" "c"))) + (custom--inhibit-theme-enable t)) + ;; Check file safety with `custom-safe-themes', prompting the + ;; user if necessary. + (cond ((not file) + (error "Unable to find theme file for `%s'" theme)) + ((or no-confirm + (eq custom-safe-themes t) + (and (memq 'default custom-safe-themes) + (equal (file-name-directory file) + (expand-file-name "themes/" data-directory)))) + ;; Theme is safe; load byte-compiled version if available. + (load (file-name-sans-extension file) nil t nil t)) + ((with-temp-buffer + (insert-file-contents file) + (let ((hash (secure-hash 'sha256 (current-buffer)))) + (when (or (member hash custom-safe-themes) + (custom-theme-load-confirm hash)) + (eval-buffer nil nil file) + t)))) + (t + (error "Unable to load theme `%s'" theme)))) + ;; Optimization: if the theme changes the `default' face, put that + ;; entry first. This avoids some `frame-set-background-mode' rigmarole + ;; by assigning the new background immediately. + (let* ((settings (get theme 'theme-settings)) + (tail settings) + found) + (while (and tail (not found)) + (and (eq (nth 0 (car tail)) 'theme-face) + (eq (nth 1 (car tail)) 'default) + (setq found (car tail))) + (setq tail (cdr tail))) + (when found + (put theme 'theme-settings (cons found (delq found settings))))) + ;; Finally, enable the theme. + (unless no-enable + (enable-theme theme)) + t) (defun custom-theme-load-confirm (hash) "Query the user about loading a Custom theme that may not be safe. -- 2.17.1 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #3: 0002-Disable-no-byte-compile-in-built-in-themes.patch --] [-- Type: text/x-diff, Size: 6291 bytes --] From 6b509915240fabeeaa4a4aedbad87f146bd61f66 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Wed, 9 May 2018 22:30:48 +0100 Subject: [PATCH 2/8] Disable no-byte-compile in built-in themes * etc/themes/adwaita-theme.el: * etc/themes/deeper-blue-theme.el: * etc/themes/dichromacy-theme.el: * etc/themes/leuven-theme.el: * etc/themes/light-blue-theme.el: * etc/themes/manoj-dark-theme.el: * etc/themes/misterioso-theme.el: * etc/themes/tango-dark-theme.el: * etc/themes/tango-theme.el: * etc/themes/tsdh-dark-theme.el: * etc/themes/tsdh-light-theme.el: * etc/themes/wheatgrass-theme.el: * etc/themes/whiteboard-theme.el: * etc/themes/wombat-theme.el: Disable no-byte-compile. https://lists.gnu.org/archive/html/emacs-devel/2018-01/msg00614.html https://lists.gnu.org/archive/html/emacs-devel/2018-02/msg00060.html --- etc/themes/adwaita-theme.el | 4 ---- etc/themes/deeper-blue-theme.el | 4 ---- etc/themes/dichromacy-theme.el | 4 ---- etc/themes/leuven-theme.el | 1 - etc/themes/light-blue-theme.el | 4 ---- etc/themes/manoj-dark-theme.el | 4 ---- etc/themes/misterioso-theme.el | 4 ---- etc/themes/tango-dark-theme.el | 4 ---- etc/themes/tango-theme.el | 4 ---- etc/themes/tsdh-dark-theme.el | 4 ---- etc/themes/tsdh-light-theme.el | 5 ----- etc/themes/wheatgrass-theme.el | 4 ---- etc/themes/whiteboard-theme.el | 4 ---- etc/themes/wombat-theme.el | 4 ---- 14 files changed, 54 deletions(-) diff --git a/etc/themes/adwaita-theme.el b/etc/themes/adwaita-theme.el index b376153510..415db8a191 100644 --- a/etc/themes/adwaita-theme.el +++ b/etc/themes/adwaita-theme.el @@ -99,8 +99,4 @@ adwaita `(diff-added ((,class (:bold t :foreground "#4E9A06")))) `(diff-removed ((,class (:bold t :foreground "#F5666D")))))) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; adwaita-theme.el ends here diff --git a/etc/themes/deeper-blue-theme.el b/etc/themes/deeper-blue-theme.el index c6aa1751f4..0700f4f23d 100644 --- a/etc/themes/deeper-blue-theme.el +++ b/etc/themes/deeper-blue-theme.el @@ -110,8 +110,4 @@ deeper-blue (provide-theme 'deeper-blue) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; deeper-blue-theme.el ends here diff --git a/etc/themes/dichromacy-theme.el b/etc/themes/dichromacy-theme.el index 793209c055..bfced43aee 100644 --- a/etc/themes/dichromacy-theme.el +++ b/etc/themes/dichromacy-theme.el @@ -122,8 +122,4 @@ dichromacy (provide-theme 'dichromacy) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; dichromacy-theme.el ends here diff --git a/etc/themes/leuven-theme.el b/etc/themes/leuven-theme.el index 5c0d19ce81..c3c666588b 100644 --- a/etc/themes/leuven-theme.el +++ b/etc/themes/leuven-theme.el @@ -708,7 +708,6 @@ leuven ;; time-stamp-format: "%:y%02m%02d.%02H%02M" ;; time-stamp-start: "Version: " ;; time-stamp-end: "$" -;; no-byte-compile: t ;; End: ;;; leuven-theme.el ends here diff --git a/etc/themes/light-blue-theme.el b/etc/themes/light-blue-theme.el index 9935c565fb..ba00db6a49 100644 --- a/etc/themes/light-blue-theme.el +++ b/etc/themes/light-blue-theme.el @@ -61,8 +61,4 @@ light-blue (provide-theme 'light-blue) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; light-blue-theme.el ends here diff --git a/etc/themes/manoj-dark-theme.el b/etc/themes/manoj-dark-theme.el index fe61441d78..ddcaa0bd99 100644 --- a/etc/themes/manoj-dark-theme.el +++ b/etc/themes/manoj-dark-theme.el @@ -700,8 +700,4 @@ manoj-dark (provide-theme 'manoj-dark) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; manoj-dark.el ends here diff --git a/etc/themes/misterioso-theme.el b/etc/themes/misterioso-theme.el index 42e448d28b..6c1eec0f42 100644 --- a/etc/themes/misterioso-theme.el +++ b/etc/themes/misterioso-theme.el @@ -103,8 +103,4 @@ misterioso (provide-theme 'misterioso) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; misterioso-theme.el ends here diff --git a/etc/themes/tango-dark-theme.el b/etc/themes/tango-dark-theme.el index 3b6eeb702e..dae77a5e62 100644 --- a/etc/themes/tango-dark-theme.el +++ b/etc/themes/tango-dark-theme.el @@ -170,8 +170,4 @@ tango-dark (provide-theme 'tango-dark) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; tango-dark-theme.el ends here diff --git a/etc/themes/tango-theme.el b/etc/themes/tango-theme.el index a7a79c04ad..4fe2480bc7 100644 --- a/etc/themes/tango-theme.el +++ b/etc/themes/tango-theme.el @@ -154,8 +154,4 @@ tango (provide-theme 'tango) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; tango-theme.el ends here diff --git a/etc/themes/tsdh-dark-theme.el b/etc/themes/tsdh-dark-theme.el index 287fef8253..c216750cb2 100644 --- a/etc/themes/tsdh-dark-theme.el +++ b/etc/themes/tsdh-dark-theme.el @@ -144,8 +144,4 @@ tsdh-dark (provide-theme 'tsdh-dark) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; tsdh-dark-theme.el ends here diff --git a/etc/themes/tsdh-light-theme.el b/etc/themes/tsdh-light-theme.el index 17a86fdbfe..ce9d1a2c3c 100644 --- a/etc/themes/tsdh-light-theme.el +++ b/etc/themes/tsdh-light-theme.el @@ -106,9 +106,4 @@ tsdh-light (provide-theme 'tsdh-light) - -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; tsdh-light-theme.el ends here diff --git a/etc/themes/wheatgrass-theme.el b/etc/themes/wheatgrass-theme.el index 9585e3aa6e..8d34c28bf4 100644 --- a/etc/themes/wheatgrass-theme.el +++ b/etc/themes/wheatgrass-theme.el @@ -83,8 +83,4 @@ wheatgrass (provide-theme 'wheatgrass) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; wheatgrass-theme.el ends here diff --git a/etc/themes/whiteboard-theme.el b/etc/themes/whiteboard-theme.el index 5db0ddd68d..fe46cb0928 100644 --- a/etc/themes/whiteboard-theme.el +++ b/etc/themes/whiteboard-theme.el @@ -100,8 +100,4 @@ whiteboard (provide-theme 'whiteboard) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; whiteboard-theme.el ends here diff --git a/etc/themes/wombat-theme.el b/etc/themes/wombat-theme.el index 583b8dc3f6..00f29bb9fa 100644 --- a/etc/themes/wombat-theme.el +++ b/etc/themes/wombat-theme.el @@ -102,8 +102,4 @@ wombat (provide-theme 'wombat) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; wombat-theme.el ends here -- 2.17.1 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #4: 0003-Fix-custom-available-themes-file-expansion.patch --] [-- Type: text/x-diff, Size: 6683 bytes --] From fe9bb45861c8f87cb62f69fb46d81286292352ab Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Wed, 2 May 2018 21:18:24 +0100 Subject: [PATCH 3/8] Fix custom-available-themes file expansion For discussion, see thread starting at https://lists.gnu.org/archive/html/emacs-devel/2018-05/msg00222.html. * lisp/custom.el: (custom-available-themes): Use directory-files instead of performing arbitrary wildcard expansion in file names. (custom-theme--load-path): Document return value. * test/lisp/custom-tests.el: New file. (custom-theme--load-path): New test. --- lisp/custom.el | 26 +++++++----- test/lisp/custom-tests.el | 87 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 10 deletions(-) create mode 100644 test/lisp/custom-tests.el diff --git a/lisp/custom.el b/lisp/custom.el index 1fed5dce53..965c817e82 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -1299,19 +1299,25 @@ custom-available-themes loaded, and no effort is made to check that the files contain valid Custom themes. For a list of loaded themes, check the variable `custom-known-themes'." - (let (sym themes) + (let ((suffix "-theme\\.el\\'") + themes) (dolist (dir (custom-theme--load-path)) - (when (file-directory-p dir) - (dolist (file (file-expand-wildcards - (expand-file-name "*-theme.el" dir) t)) - (setq file (file-name-nondirectory file)) - (and (string-match "\\`\\(.+\\)-theme.el\\'" file) - (setq sym (intern (match-string 1 file))) - (custom-theme-name-valid-p sym) - (push sym themes))))) - (nreverse (delete-dups themes)))) + ;; Can't load `cl-lib' at top-level due to bootstrapping issues. + (when (fboundp 'cl-assert) + (cl-assert + (file-directory-p dir) t + "Non-existent directory in `custom-theme-load-path' expansion: %s")) + (dolist (file (directory-files dir nil suffix)) + (let ((theme (intern (substring file 0 (string-match-p suffix file))))) + (and (custom-theme-name-valid-p theme) + (not (memq theme themes)) + (push theme themes))))) + (nreverse themes))) (defun custom-theme--load-path () + "Expand `custom-theme-load-path' into a list of directories. +Members of `custom-theme-load-path' that either don't exist or +are not directories are omitted from the expansion." (let (lpath) (dolist (f custom-theme-load-path) (cond ((eq f 'custom-theme-directory) diff --git a/test/lisp/custom-tests.el b/test/lisp/custom-tests.el new file mode 100644 index 0000000000..96887f8f5f --- /dev/null +++ b/test/lisp/custom-tests.el @@ -0,0 +1,87 @@ +;;; custom-tests.el --- tests for custom.el -*- lexical-binding: t -*- + +;; Copyright (C) 2018 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs 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. + +;; GNU Emacs 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 program. If not, see <https://www.gnu.org/licenses/>. + +;;; Code: + +(require 'ert) + +(ert-deftest custom-theme--load-path () + "Test `custom-theme--load-path' behavior." + (let ((tmpdir (file-name-as-directory (make-temp-file "custom-tests-" t)))) + (unwind-protect + ;; Create all temporary files under the same deletable parent. + (let ((temporary-file-directory tmpdir)) + ;; Path is empty. + (let ((custom-theme-load-path ())) + (should (null (custom-theme--load-path)))) + + ;; Path comprises non-existent file. + (let* ((name (make-temp-name tmpdir)) + (custom-theme-load-path (list name))) + (should (not (file-exists-p name))) + (should (null (custom-theme--load-path)))) + + ;; Path comprises existing file. + (let* ((file (make-temp-file "file")) + (custom-theme-load-path (list file))) + (should (file-exists-p file)) + (should (not (file-directory-p file))) + (should (null (custom-theme--load-path)))) + + ;; Path comprises existing directory. + (let* ((dir (make-temp-file "dir" t)) + (custom-theme-load-path (list dir))) + (should (file-directory-p dir)) + (should (equal (custom-theme--load-path) custom-theme-load-path))) + + ;; Expand `custom-theme-directory' path element. + (let ((custom-theme-load-path '(custom-theme-directory))) + (let ((custom-theme-directory (make-temp-name tmpdir))) + (should (not (file-exists-p custom-theme-directory))) + (should (null (custom-theme--load-path)))) + (let ((custom-theme-directory (make-temp-file "file"))) + (should (file-exists-p custom-theme-directory)) + (should (not (file-directory-p custom-theme-directory))) + (should (null (custom-theme--load-path)))) + (let ((custom-theme-directory (make-temp-file "dir" t))) + (should (file-directory-p custom-theme-directory)) + (should (equal (custom-theme--load-path) + (list custom-theme-directory))))) + + ;; Expand t path element. + (let ((custom-theme-load-path '(t))) + (let ((data-directory (make-temp-name tmpdir))) + (should (not (file-exists-p data-directory))) + (should (null (custom-theme--load-path)))) + (let ((data-directory tmpdir) + (themedir (expand-file-name "themes" tmpdir))) + (should (not (file-exists-p themedir))) + (should (null (custom-theme--load-path))) + (with-temp-file themedir) + (should (file-exists-p themedir)) + (should (not (file-directory-p themedir))) + (should (null (custom-theme--load-path))) + (delete-file themedir) + (make-directory themedir) + (should (file-directory-p themedir)) + (should (equal (custom-theme--load-path) (list themedir)))))) + (when (file-directory-p tmpdir) + (delete-directory tmpdir t))))) + +;;; custom-tests.el ends here -- 2.17.1 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #5: 0004-lisp-custom.el-Use-lexical-binding.patch --] [-- Type: text/x-diff, Size: 7797 bytes --] From f809fccdbd12aea44586b6b1c7b0102648c1351b Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Fri, 11 May 2018 16:09:57 +0100 Subject: [PATCH 4/8] * lisp/custom.el: Use lexical-binding Remove duplicate 'Custom Themes' comment heading. (deftheme, custom-declare-theme): Fix advertised calling convention. (custom-enabled-themes): Fix message grammar. --- lisp/custom.el | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/lisp/custom.el b/lisp/custom.el index 965c817e82..381636e4c2 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -1,4 +1,4 @@ -;;; custom.el --- tools for declaring and initializing options +;;; custom.el --- tools for declaring and initializing options -*- lexical-binding: t -*- ;; ;; Copyright (C) 1996-1997, 1999, 2001-2018 Free Software Foundation, ;; Inc. @@ -150,7 +150,7 @@ custom-declare-variable (put symbol 'force-value nil)) (if (keywordp doc) (error "Doc string is missing")) - (let ((initialize 'custom-initialize-reset) + (let ((initialize #'custom-initialize-reset) (requests nil)) (unless (memq :group args) (custom-add-to-group (custom-current-group) symbol 'custom-variable)) @@ -426,7 +426,7 @@ custom-current-group (defun custom-declare-group (symbol members doc &rest args) "Like `defgroup', but SYMBOL is evaluated as a normal argument." (while members - (apply 'custom-add-to-group symbol (car members)) + (apply #'custom-add-to-group symbol (car members)) (setq members (cdr members))) (when doc ;; This text doesn't get into DOC. @@ -618,11 +618,8 @@ custom-note-var-changed The result is that the change is treated as having been made through Custom." (put variable 'customized-value (list (custom-quote (eval variable))))) -\f -;;; Custom Themes - -;;; Loading files needed to customize a symbol. -;;; This is in custom.el because menu-bar.el needs it for toggle cmds. +;; Loading files needed to customize a symbol. +;; This is in custom.el because menu-bar.el needs it for toggle cmds. (defvar custom-load-recursion nil "Hack to avoid recursive dependencies.") @@ -715,7 +712,7 @@ customize-mark-to-save Return non-nil if the `saved-value' property actually changed." (custom-load-symbol symbol) - (let* ((get (or (get symbol 'custom-get) 'default-value)) + (let* ((get (or (get symbol 'custom-get) #'default-value)) (value (funcall get symbol)) (saved (get symbol 'saved-value)) (standard (get symbol 'standard-value)) @@ -744,7 +741,7 @@ customize-mark-as-set Return non-nil if the `customized-value' property actually changed." (custom-load-symbol symbol) - (let* ((get (or (get symbol 'custom-get) 'default-value)) + (let* ((get (or (get symbol 'custom-get) #'default-value)) (value (funcall get symbol)) (customized (get symbol 'customized-value)) (old (or (get symbol 'saved-value) (get symbol 'standard-value)))) @@ -776,7 +773,7 @@ custom-reevaluate-setting ;; always do the funcall step, even if symbol was not bound before. (or (default-boundp symbol) (eval `(defvar ,symbol nil))) ; reset below, so any value is fine - (funcall (or (get symbol 'custom-set) 'set-default) + (funcall (or (get symbol 'custom-set) #'set-default) symbol (eval (car (or (get symbol 'saved-value) (get symbol 'standard-value)))))) @@ -941,7 +938,7 @@ custom-set-variables REQUEST is a list of features we must require in order to handle SYMBOL properly. COMMENT is a comment string about SYMBOL." - (apply 'custom-theme-set-variables 'user args)) + (apply #'custom-theme-set-variables 'user args)) (defun custom-theme-set-variables (theme &rest args) "Initialize variables for theme THEME according to settings in ARGS. @@ -989,8 +986,8 @@ custom-theme-set-variables set) (when requests (put symbol 'custom-requests requests) - (mapc 'require requests)) - (setq set (or (get symbol 'custom-set) 'custom-set-default)) + (mapc #'require requests)) + (setq set (or (get symbol 'custom-set) #'custom-set-default)) (put symbol 'saved-value (list value)) (put symbol 'saved-variable-comment comment) ;; Allow for errors in the case where the setter has @@ -1086,26 +1083,29 @@ custom--sort-vars-1 ;; they were used to supply keyword-value pairs like `:immediate', ;; `:variable-reset-string', etc. We don't use any of these, so ignore them. -(defmacro deftheme (theme &optional doc &rest ignored) +(defmacro deftheme (theme &optional doc &rest _ignored) "Declare THEME to be a Custom theme. The optional argument DOC is a doc string describing the theme. Any theme `foo' should be defined in a file called `foo-theme.el'; see `custom-make-theme-feature' for more information." - (declare (doc-string 2)) + (declare (doc-string 2) + (advertised-calling-convention (theme &optional doc) "22.1")) (let ((feature (custom-make-theme-feature theme))) ;; It is better not to use backquote in this file, ;; because that makes a bootstrapping problem ;; if you need to recompile all the Lisp files using interpreted code. (list 'custom-declare-theme (list 'quote theme) (list 'quote feature) doc))) -(defun custom-declare-theme (theme feature &optional doc &rest ignored) +(defun custom-declare-theme (theme feature &optional doc &rest _ignored) "Like `deftheme', but THEME is evaluated as a normal argument. FEATURE is the feature this theme provides. Normally, this is a symbol created from THEME by `custom-make-theme-feature'." + (declare (advertised-calling-convention (theme feature &optional doc) "22.1")) (unless (custom-theme-name-valid-p theme) (error "Custom theme cannot be named %S" theme)) - (add-to-list 'custom-known-themes theme) + (unless (memq theme custom-known-themes) + (push theme custom-known-themes)) (put theme 'theme-feature feature) (when doc (put theme 'theme-documentation doc))) @@ -1206,7 +1206,7 @@ load-theme (interactive (list (intern (completing-read "Load custom theme: " - (mapcar 'symbol-name + (mapcar #'symbol-name (custom-available-themes)))) nil nil)) (unless (custom-theme-name-valid-p theme) @@ -1395,9 +1395,9 @@ custom-enabled-themes themes (delq theme themes))))) (enable-theme 'user) (custom-set-default symbol themes) - (if failures - (message "Failed to enable theme: %s" - (mapconcat 'symbol-name failures ", ")))))) + (when failures + (message "Failed to enable theme(s): %s" + (mapconcat #'symbol-name failures ", ")))))) (defsubst custom-theme-enabled-p (theme) "Return non-nil if THEME is enabled." @@ -1409,7 +1409,7 @@ disable-theme (interactive (list (intern (completing-read "Disable custom theme: " - (mapcar 'symbol-name custom-enabled-themes) + (mapcar #'symbol-name custom-enabled-themes) nil t)))) (when (custom-theme-enabled-p theme) (let ((settings (get theme 'theme-settings))) @@ -1475,7 +1475,7 @@ custom-theme-recalc-variable (if (and valspec (or (get variable 'force-value) (default-boundp variable))) - (funcall (or (get variable 'custom-set) 'set-default) variable + (funcall (or (get variable 'custom-set) #'set-default) variable (eval (car valspec)))))) (defun custom-theme-recalc-face (face) @@ -1516,7 +1516,7 @@ custom-reset-variables (VARIABLE IGNORED) This means reset VARIABLE. (The argument IGNORED is ignored)." - (apply 'custom-theme-reset-variables 'user args)) + (apply #'custom-theme-reset-variables 'user args)) ;;; The End. -- 2.17.1 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #6: 0005-lisp-cus-theme.el-Use-lexical-binding.patch --] [-- Type: text/x-diff, Size: 5907 bytes --] From d9881e411f2e8d10908d15f25733be189b66721f Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Fri, 11 May 2018 15:35:09 +0100 Subject: [PATCH 5/8] * lisp/cus-theme.el: Use lexical-binding --- lisp/cus-theme.el | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/lisp/cus-theme.el b/lisp/cus-theme.el index e5e787771b..53389956ad 100644 --- a/lisp/cus-theme.el +++ b/lisp/cus-theme.el @@ -1,4 +1,4 @@ -;;; cus-theme.el -- custom theme creation user interface +;;; cus-theme.el -- custom theme creation user interface -*- lexical-binding: t -*- ;; ;; Copyright (C) 2001-2018 Free Software Foundation, Inc. ;; @@ -47,7 +47,7 @@ custom-new-theme-mode Do not call this mode function yourself. It is meant for internal use." (use-local-map custom-new-theme-mode-map) (custom--initialize-widget-variables) - (set (make-local-variable 'revert-buffer-function) 'custom-theme-revert)) + (set (make-local-variable 'revert-buffer-function) #'custom-theme-revert)) (put 'custom-new-theme-mode 'mode-class 'special) (defvar custom-theme-name nil) @@ -118,13 +118,13 @@ customize-create-theme :tag " Visit Theme " :help-echo "Insert the settings of a pre-defined theme." :action (lambda (_widget &optional _event) - (call-interactively 'custom-theme-visit-theme))) + (call-interactively #'custom-theme-visit-theme))) (widget-insert " ") (widget-create 'push-button :tag " Merge Theme " :help-echo "Merge in the settings of a pre-defined theme." :action (lambda (_widget &optional _event) - (call-interactively 'custom-theme-merge-theme))) + (call-interactively #'custom-theme-merge-theme))) (widget-insert " ") (widget-create 'push-button :tag " Revert " @@ -142,7 +142,7 @@ customize-create-theme (widget-create 'text :value (format-time-string "Created %Y-%m-%d."))) (widget-create 'push-button - :notify (function custom-theme-write) + :notify #'custom-theme-write " Save Theme ") (when (eq theme 'user) (setq custom-theme--migrate-settings t) @@ -188,7 +188,7 @@ customize-create-theme :mouse-face 'highlight :pressed-face 'highlight :action (lambda (_widget &optional _event) - (call-interactively 'custom-theme-add-face))) + (call-interactively #'custom-theme-add-face))) ;; If THEME is non-nil, insert all of that theme's variables. (widget-insert "\n\n Theme variables:\n ") @@ -207,7 +207,7 @@ customize-create-theme :mouse-face 'highlight :pressed-face 'highlight :action (lambda (_widget &optional _event) - (call-interactively 'custom-theme-add-variable))) + (call-interactively #'custom-theme-add-variable))) (widget-insert ?\n) (widget-setup) (goto-char (point-min)) @@ -254,7 +254,7 @@ custom-theme-add-var-1 :tag (custom-unlispify-tag-name symbol) :value symbol :shown-value (list val) - :notify 'ignore + :notify #'ignore :custom-level 0 :custom-state 'hidden :custom-style 'simple)) @@ -313,7 +313,7 @@ custom-theme-visit-theme (interactive (list (intern (completing-read "Find custom theme: " - (mapcar 'symbol-name + (mapcar #'symbol-name (custom-available-themes)))))) (unless (custom-theme-name-valid-p theme) (error "No valid theme named `%s'" theme)) @@ -328,7 +328,7 @@ custom-theme-merge-theme (interactive (list (intern (completing-read "Merge custom theme: " - (mapcar 'symbol-name + (mapcar #'symbol-name (custom-available-themes)))))) (unless (eq theme 'user) (unless (custom-theme-name-valid-p theme) @@ -343,8 +343,8 @@ custom-theme-merge-theme (memq name '(custom-enabled-themes custom-safe-themes))) (funcall (if option - 'custom-theme-add-variable - 'custom-theme-add-face) + #'custom-theme-add-variable + #'custom-theme-add-face) name value))))) theme) @@ -475,7 +475,7 @@ describe-theme (interactive (list (intern (completing-read "Describe custom theme: " - (mapcar 'symbol-name + (mapcar #'symbol-name (custom-available-themes)))))) (unless (custom-theme-name-valid-p theme) (error "Invalid theme name `%s'" theme)) @@ -616,11 +616,11 @@ customize-themes (widget-create 'push-button :tag " Save Theme Settings " :help-echo "Save the selected themes for future sessions." - :action 'custom-theme-save) + :action #'custom-theme-save) (widget-insert ?\n) (widget-create 'checkbox :value custom-theme-allow-multiple-selections - :action 'custom-theme-selections-toggle) + :action #'custom-theme-selections-toggle) (widget-insert (propertize " Select more than one theme at a time" 'face '(variable-pitch (:height 0.9)))) @@ -632,13 +632,13 @@ customize-themes :value (custom-theme-enabled-p theme) :theme-name theme :help-echo help-echo - :action 'custom-theme-checkbox-toggle)) + :action #'custom-theme-checkbox-toggle)) (push (cons theme widget) custom--listed-themes) (widget-create-child-and-convert widget 'push-button :button-face-get 'ignore :mouse-face-get 'ignore :value (format " %s" theme) - :action 'widget-parent-action + :action #'widget-parent-action :help-echo help-echo) (widget-insert " -- " (propertize (custom-theme-summary theme) -- 2.17.1 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #7: 0006-Minor-custom.el-simplifications.patch --] [-- Type: text/x-diff, Size: 7892 bytes --] From 537cfe5702d86eebcfc4909ed93fced71d218bf8 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Thu, 31 May 2018 18:37:02 +0100 Subject: [PATCH 6/8] Minor custom.el simplifications * lisp/custom.el (custom-quote): Duplicate macroexp-quote. (custom-load-symbol, customize-mark-to-save, customize-mark-as-set) (custom-theme-name-valid-p, enable-theme, custom-enabled-themes) (disable-theme): Simplify logic. --- lisp/custom.el | 103 ++++++++++++++++++++++--------------------------- 1 file changed, 46 insertions(+), 57 deletions(-) diff --git a/lisp/custom.el b/lisp/custom.el index 381636e4c2..1233e44d05 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -630,14 +630,12 @@ custom-load-symbol (let ((custom-load-recursion t)) ;; Load these files if not already done, ;; to make sure we know all the dependencies of SYMBOL. - (condition-case nil - (require 'cus-load) - (error nil)) - (condition-case nil - (require 'cus-start) - (error nil)) + (ignore-errors + (require 'cus-load)) + (ignore-errors + (require 'cus-start)) (dolist (load (get symbol 'custom-loads)) - (cond ((symbolp load) (condition-case nil (require load) (error nil))) + (cond ((symbolp load) (ignore-errors (require load))) ;; This is subsumed by the test below, but it's much faster. ((assoc load load-history)) ;; This was just (assoc (locate-library load) load-history) @@ -655,7 +653,7 @@ custom-load-symbol ;; We are still loading it when we call this, ;; and it is not in load-history yet. ((equal load "cus-edit")) - (t (condition-case nil (load load) (error nil)))))))) + (t (ignore-errors (load load)))))))) \f (defvar custom-local-buffer nil "Non-nil, in a Customization buffer, means customize a specific buffer. @@ -688,16 +686,12 @@ custom-set-minor-mode (defun custom-quote (sexp) "Quote SEXP if it is not self quoting." - (if (or (memq sexp '(t nil)) - (keywordp sexp) - (and (listp sexp) - (memq (car sexp) '(lambda))) - (stringp sexp) - (numberp sexp) - (vectorp sexp) -;;; (and (fboundp 'characterp) -;;; (characterp sexp)) - ) + ;; Can't use `macroexp-quote' because it is loaded after `custom.el' + ;; during bootstrap. See `loadup.el'. + (if (and (not (consp sexp)) + (or (keywordp sexp) + (not (symbolp sexp)) + (booleanp sexp))) sexp (list 'quote sexp))) @@ -718,12 +712,10 @@ customize-mark-to-save (standard (get symbol 'standard-value)) (comment (get symbol 'customized-variable-comment))) ;; Save default value if different from standard value. - (if (or (null standard) - (not (equal value (condition-case nil - (eval (car standard)) - (error nil))))) - (put symbol 'saved-value (list (custom-quote value))) - (put symbol 'saved-value nil)) + (put symbol 'saved-value + (unless (and standard + (equal value (ignore-errors (eval (car standard))))) + (list (custom-quote value)))) ;; Clear customized information (set, but not saved). (put symbol 'customized-value nil) ;; Save any comment that might have been set. @@ -747,9 +739,8 @@ customize-mark-as-set (old (or (get symbol 'saved-value) (get symbol 'standard-value)))) ;; Mark default value as set if different from old value. (if (not (and old - (equal value (condition-case nil - (eval (car old)) - (error nil))))) + (equal value (ignore-errors + (eval (car old)))))) (progn (put symbol 'customized-value (list (custom-quote value))) (custom-push-theme 'theme-value symbol 'user 'set (custom-quote value))) @@ -1284,11 +1275,9 @@ custom-theme-load-confirm (defun custom-theme-name-valid-p (name) "Return t if NAME is a valid name for a Custom theme, nil otherwise. NAME should be a symbol." - (and (symbolp name) - name - (not (or (zerop (length (symbol-name name))) - (eq name 'user) - (eq name 'changed))))) + (and (not (memq name '(nil user changed))) + (symbolp name) + (not (string= "" (symbol-name name))))) (defun custom-available-themes () "Return a list of Custom themes available for loading. @@ -1340,8 +1329,8 @@ enable-theme (completing-read "Enable custom theme: " obarray (lambda (sym) (get sym 'theme-settings)) t)))) - (if (not (custom-theme-p theme)) - (error "Undefined Custom theme %s" theme)) + (unless (custom-theme-p theme) + (error "Undefined Custom theme %s" theme)) (let ((settings (get theme 'theme-settings))) ;; Loop through theme settings, recalculating vars/faces. (dolist (s settings) @@ -1381,18 +1370,18 @@ custom-enabled-themes (let (failures) (setq themes (delq 'user (delete-dups themes))) ;; Disable all themes not in THEMES. - (if (boundp symbol) - (dolist (theme (symbol-value symbol)) - (if (not (memq theme themes)) - (disable-theme theme)))) + (dolist (theme (and (boundp symbol) + (symbol-value symbol))) + (unless (memq theme themes) + (disable-theme theme))) ;; Call `enable-theme' or `load-theme' on each of THEMES. (dolist (theme (reverse themes)) (condition-case nil (if (custom-theme-p theme) (enable-theme theme) (load-theme theme)) - (error (setq failures (cons theme failures) - themes (delq theme themes))))) + (error (push theme failures) + (setq themes (delq theme themes))))) (enable-theme 'user) (custom-set-default symbol themes) (when failures @@ -1425,23 +1414,23 @@ disable-theme ;; If the face spec specified by this theme is in the ;; saved-face property, reset that property. (when (equal (nth 3 s) (get symbol 'saved-face)) - (put symbol 'saved-face (and val (cadr (car val))))))))) - ;; Recompute faces on all frames. - (dolist (frame (frame-list)) - ;; We must reset the fg and bg color frame parameters, or - ;; `face-set-after-frame-default' will use the existing - ;; parameters, which could be from the disabled theme. - (set-frame-parameter frame 'background-color - (custom--frame-color-default - frame :background "background" "Background" - "unspecified-bg" "white")) - (set-frame-parameter frame 'foreground-color - (custom--frame-color-default - frame :foreground "foreground" "Foreground" - "unspecified-fg" "black")) - (face-set-after-frame-default frame)) - (setq custom-enabled-themes - (delq theme custom-enabled-themes))))) + (put symbol 'saved-face (cadar val)))))))) + ;; Recompute faces on all frames. + (dolist (frame (frame-list)) + ;; We must reset the fg and bg color frame parameters, or + ;; `face-set-after-frame-default' will use the existing + ;; parameters, which could be from the disabled theme. + (set-frame-parameter frame 'background-color + (custom--frame-color-default + frame :background "background" "Background" + "unspecified-bg" "white")) + (set-frame-parameter frame 'foreground-color + (custom--frame-color-default + frame :foreground "foreground" "Foreground" + "unspecified-fg" "black")) + (face-set-after-frame-default frame)) + (setq custom-enabled-themes + (delq theme custom-enabled-themes)))) ;; Only used if window-system not null. (declare-function x-get-resource "frame.c" -- 2.17.1 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #8: 0007-Minor-cus-theme.el-simplifications.patch --] [-- Type: text/x-diff, Size: 3932 bytes --] From 41e2217167b4186467d75aff7faaeceb34813a5f Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Thu, 10 May 2018 03:08:10 +0100 Subject: [PATCH 7/8] Minor cus-theme.el simplifications * lisp/cus-theme.el (custom-new-theme-mode, customize-themes) (custom-theme-choose-mode): Use setq-local. (customize-create-theme): Ditto. Use delete-all-overlays. (describe-theme-1, custom-theme-summary): Simplify logic. --- lisp/cus-theme.el | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/lisp/cus-theme.el b/lisp/cus-theme.el index 53389956ad..995c55b2b2 100644 --- a/lisp/cus-theme.el +++ b/lisp/cus-theme.el @@ -47,7 +47,7 @@ custom-new-theme-mode Do not call this mode function yourself. It is meant for internal use." (use-local-map custom-new-theme-mode-map) (custom--initialize-widget-variables) - (set (make-local-variable 'revert-buffer-function) #'custom-theme-revert)) + (setq-local revert-buffer-function #'custom-theme-revert)) (put 'custom-new-theme-mode 'mode-class 'special) (defvar custom-theme-name nil) @@ -93,15 +93,14 @@ customize-create-theme (switch-to-buffer (get-buffer-create (or buffer "*Custom Theme*"))) (let ((inhibit-read-only t)) (erase-buffer) - (dolist (ov (overlays-in (point-min) (point-max))) - (delete-overlay ov))) + (delete-all-overlays)) (custom-new-theme-mode) (make-local-variable 'custom-theme-name) - (set (make-local-variable 'custom-theme--save-name) theme) - (set (make-local-variable 'custom-theme-faces) nil) - (set (make-local-variable 'custom-theme-variables) nil) - (set (make-local-variable 'custom-theme-description) "") - (set (make-local-variable 'custom-theme--migrate-settings) nil) + (setq-local custom-theme--save-name theme) + (setq-local custom-theme-faces nil) + (setq-local custom-theme-variables nil) + (setq-local custom-theme-description "") + (setq-local custom-theme--migrate-settings nil) (make-local-variable 'custom-theme-insert-face-marker) (make-local-variable 'custom-theme-insert-variable-marker) (make-local-variable 'custom-theme--listed-faces) @@ -513,8 +512,7 @@ describe-theme-1 (condition-case nil (read (current-buffer)) (end-of-file nil))))) - (and sexp (listp sexp) - (eq (car sexp) 'deftheme) + (and (eq (car-safe sexp) 'deftheme) (setq doc (nth 2 sexp))))))) (princ "\n\nDocumentation:\n") (princ (if (stringp doc) @@ -552,10 +550,10 @@ custom-theme-choose-mode Do not call this mode function yourself. It is meant for internal use." (use-local-map custom-theme-choose-mode-map) (custom--initialize-widget-variables) - (set (make-local-variable 'revert-buffer-function) - (lambda (_ignore-auto noconfirm) - (when (or noconfirm (y-or-n-p "Discard current choices? ")) - (customize-themes (current-buffer)))))) + (setq-local revert-buffer-function + (lambda (_ignore-auto noconfirm) + (when (or noconfirm (y-or-n-p "Discard current choices? ")) + (customize-themes (current-buffer)))))) (put 'custom-theme-choose-mode 'mode-class 'special) ;;;###autoload @@ -568,7 +566,7 @@ customize-themes (let ((inhibit-read-only t)) (erase-buffer)) (custom-theme-choose-mode) - (set (make-local-variable 'custom--listed-themes) nil) + (setq-local custom--listed-themes nil) (make-local-variable 'custom-theme-allow-multiple-selections) (and (null custom-theme-allow-multiple-selections) (> (length custom-enabled-themes) 1) @@ -662,8 +660,7 @@ custom-theme-summary (condition-case nil (read (current-buffer)) (end-of-file nil))))) - (and sexp (listp sexp) - (eq (car sexp) 'deftheme) + (and (eq (car-safe sexp) 'deftheme) (setq doc (nth 2 sexp)))))))) (cond ((null doc) "(no documentation available)") -- 2.17.1 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #9: 0008-Tweak-subr-x.el-substring-functions.patch --] [-- Type: text/x-diff, Size: 4709 bytes --] From 460204efa19cadf5f7d89175125b24ab5fba0ccd Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Fri, 1 Jun 2018 21:58:10 +0100 Subject: [PATCH 8/8] Tweak subr-x.el substring functions * lisp/emacs-lisp/subr-x.el (string-join): #'-quote function symbol. (string-trim-left, string-trim-right): Make better use of substring for minor speedup. * test/lisp/emacs-lisp/subr-x-tests.el (subr-x-test-string-trim-left, subr-x-test-string-trim-right) (subr-x-test-string-remove-prefix) (subr-x-test-string-remove-suffix): New tests. --- lisp/emacs-lisp/subr-x.el | 12 +++---- test/lisp/emacs-lisp/subr-x-tests.el | 47 ++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el index 7fab9083e8..eb3ec85ecc 100644 --- a/lisp/emacs-lisp/subr-x.el +++ b/lisp/emacs-lisp/subr-x.el @@ -211,7 +211,7 @@ string-empty-p (defsubst string-join (strings &optional separator) "Join all STRINGS using SEPARATOR." - (mapconcat 'identity strings separator)) + (mapconcat #'identity strings separator)) (define-obsolete-function-alias 'string-reverse 'reverse "25.1") @@ -219,17 +219,17 @@ string-trim-left "Trim STRING of leading string matching REGEXP. REGEXP defaults to \"[ \\t\\n\\r]+\"." - (if (string-match (concat "\\`\\(?:" (or regexp "[ \t\n\r]+")"\\)") string) - (replace-match "" t t string) + (if (string-match (concat "\\`\\(?:" (or regexp "[ \t\n\r]+") "\\)") string) + (substring string (match-end 0)) string)) (defsubst string-trim-right (string &optional regexp) "Trim STRING of trailing string matching REGEXP. REGEXP defaults to \"[ \\t\\n\\r]+\"." - (if (string-match (concat "\\(?:" (or regexp "[ \t\n\r]+") "\\)\\'") string) - (replace-match "" t t string) - string)) + (let ((i (string-match-p (concat "\\(?:" (or regexp "[ \t\n\r]+") "\\)\\'") + string))) + (if i (substring string 0 i) string))) (defsubst string-trim (string &optional trim-left trim-right) "Trim STRING of leading and trailing strings matching TRIM-LEFT and TRIM-RIGHT. diff --git a/test/lisp/emacs-lisp/subr-x-tests.el b/test/lisp/emacs-lisp/subr-x-tests.el index f7f0ef384f..81467bab2d 100644 --- a/test/lisp/emacs-lisp/subr-x-tests.el +++ b/test/lisp/emacs-lisp/subr-x-tests.el @@ -532,6 +532,53 @@ (format "abs sum is: %s")) "abs sum is: 15"))) +\f +;; Substring tests + +(ert-deftest subr-x-test-string-trim-left () + "Test `string-trim-left' behavior." + (should (equal (string-trim-left "") "")) + (should (equal (string-trim-left " \t\n\r") "")) + (should (equal (string-trim-left " \t\n\ra") "a")) + (should (equal (string-trim-left "a \t\n\r") "a \t\n\r")) + (should (equal (string-trim-left "" "") "")) + (should (equal (string-trim-left "a" "") "a")) + (should (equal (string-trim-left "aa" "a*") "")) + (should (equal (string-trim-left "ba" "a*") "ba")) + (should (equal (string-trim-left "aa" "a*?") "aa")) + (should (equal (string-trim-left "aa" "a+?") "a"))) + +(ert-deftest subr-x-test-string-trim-right () + "Test `string-trim-right' behavior." + (should (equal (string-trim-right "") "")) + (should (equal (string-trim-right " \t\n\r") "")) + (should (equal (string-trim-right " \t\n\ra") " \t\n\ra")) + (should (equal (string-trim-right "a \t\n\r") "a")) + (should (equal (string-trim-right "" "") "")) + (should (equal (string-trim-right "a" "") "a")) + (should (equal (string-trim-right "aa" "a*") "")) + (should (equal (string-trim-right "ab" "a*") "ab")) + (should (equal (string-trim-right "aa" "a*?") ""))) + +(ert-deftest subr-x-test-string-remove-prefix () + "Test `string-remove-prefix' behavior." + (should (equal (string-remove-prefix "" "") "")) + (should (equal (string-remove-prefix "" "a") "a")) + (should (equal (string-remove-prefix "a" "") "")) + (should (equal (string-remove-prefix "a" "b") "b")) + (should (equal (string-remove-prefix "a" "a") "")) + (should (equal (string-remove-prefix "a" "aa") "a")) + (should (equal (string-remove-prefix "a" "ab") "b"))) + +(ert-deftest subr-x-test-string-remove-suffix () + "Test `string-remove-suffix' behavior." + (should (equal (string-remove-suffix "" "") "")) + (should (equal (string-remove-suffix "" "a") "a")) + (should (equal (string-remove-suffix "a" "") "")) + (should (equal (string-remove-suffix "a" "b") "b")) + (should (equal (string-remove-suffix "a" "a") "")) + (should (equal (string-remove-suffix "a" "aa") "a")) + (should (equal (string-remove-suffix "a" "ba") "b"))) (provide 'subr-x-tests) ;;; subr-x-tests.el ends here -- 2.17.1 ^ permalink raw reply related [flat|nested] 33+ messages in thread
* Re: Byte-compilation of custom themes 2018-06-03 17:48 ` Basil L. Contovounesios @ 2018-06-03 20:22 ` Stefan Monnier 2018-06-04 1:33 ` Basil L. Contovounesios 0 siblings, 1 reply; 33+ messages in thread From: Stefan Monnier @ 2018-06-03 20:22 UTC (permalink / raw To: Basil L. Contovounesios; +Cc: Eli Zaretskii, emacs-devel > Fair enough, though it's looking like the simplest solution is to keep > the original (when (file-directory-p dir) ...) check and avoid cl-lib > altogether. Agreed, with a comment explaining that cl-lib macros can't be used at this point for bootstrap reasons. Stefan ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Byte-compilation of custom themes 2018-06-03 20:22 ` Stefan Monnier @ 2018-06-04 1:33 ` Basil L. Contovounesios 2018-07-03 7:57 ` Basil L. Contovounesios 0 siblings, 1 reply; 33+ messages in thread From: Basil L. Contovounesios @ 2018-06-04 1:33 UTC (permalink / raw To: Stefan Monnier; +Cc: Eli Zaretskii, emacs-devel [-- Attachment #1: Type: text/plain, Size: 688 bytes --] Stefan Monnier <monnier@IRO.UMontreal.CA> writes: >> Fair enough, though it's looking like the simplest solution is to keep >> the original (when (file-directory-p dir) ...) check and avoid cl-lib >> altogether. > > Agreed, with a comment explaining that cl-lib macros can't be used at > this point for bootstrap reasons. How's the attached (see [PATCH 3/8])? Too verbose? P.S. I have been informed off-list by a fellow emacs-devel subscriber that multiple copies of some of my emails are being repeatedly delivered to them. Has anyone else experienced this? If so, any advice on how to fix this would be much appreciated. Sorry in advance. Thanks, -- Basil [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: 0001-Improve-loading-of-byte-compiled-custom-themes.patch --] [-- Type: text/x-diff, Size: 4290 bytes --] From 9efc72cc95531d47c4582bdf861b1a91800671e3 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Wed, 9 May 2018 22:20:47 +0100 Subject: [PATCH 1/8] Improve loading of byte-compiled custom themes * lisp/custom.el (load-theme): Load byte-compiled file of safe themes when available. https://lists.gnu.org/archive/html/emacs-devel/2018-01/msg00614.html https://lists.gnu.org/archive/html/emacs-devel/2018-02/msg00060.html --- lisp/custom.el | 78 ++++++++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 37 deletions(-) diff --git a/lisp/custom.el b/lisp/custom.el index b7539685a8..1fed5dce53 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -1221,43 +1221,47 @@ load-theme (put theme 'theme-settings nil) (put theme 'theme-feature nil) (put theme 'theme-documentation nil)) - (let ((fn (locate-file (concat (symbol-name theme) "-theme.el") - (custom-theme--load-path) - '("" "c")))) - (unless fn - (error "Unable to find theme file for `%s'" theme)) - (with-temp-buffer - (insert-file-contents fn) - ;; Check file safety with `custom-safe-themes', prompting the - ;; user if necessary. - (when (or no-confirm - (eq custom-safe-themes t) - (and (memq 'default custom-safe-themes) - (equal (file-name-directory fn) - (expand-file-name "themes/" data-directory))) - (let ((hash (secure-hash 'sha256 (current-buffer)))) - (or (member hash custom-safe-themes) - (custom-theme-load-confirm hash)))) - (let ((custom--inhibit-theme-enable t) - (buffer-file-name fn)) ;For load-history. - (eval-buffer)) - ;; Optimization: if the theme changes the `default' face, put that - ;; entry first. This avoids some `frame-set-background-mode' rigmarole - ;; by assigning the new background immediately. - (let* ((settings (get theme 'theme-settings)) - (tail settings) - found) - (while (and tail (not found)) - (and (eq (nth 0 (car tail)) 'theme-face) - (eq (nth 1 (car tail)) 'default) - (setq found (car tail))) - (setq tail (cdr tail))) - (if found - (put theme 'theme-settings (cons found (delq found settings))))) - ;; Finally, enable the theme. - (unless no-enable - (enable-theme theme)) - t)))) + (let ((file (locate-file (concat (symbol-name theme) "-theme.el") + (custom-theme--load-path) + '("" "c"))) + (custom--inhibit-theme-enable t)) + ;; Check file safety with `custom-safe-themes', prompting the + ;; user if necessary. + (cond ((not file) + (error "Unable to find theme file for `%s'" theme)) + ((or no-confirm + (eq custom-safe-themes t) + (and (memq 'default custom-safe-themes) + (equal (file-name-directory file) + (expand-file-name "themes/" data-directory)))) + ;; Theme is safe; load byte-compiled version if available. + (load (file-name-sans-extension file) nil t nil t)) + ((with-temp-buffer + (insert-file-contents file) + (let ((hash (secure-hash 'sha256 (current-buffer)))) + (when (or (member hash custom-safe-themes) + (custom-theme-load-confirm hash)) + (eval-buffer nil nil file) + t)))) + (t + (error "Unable to load theme `%s'" theme)))) + ;; Optimization: if the theme changes the `default' face, put that + ;; entry first. This avoids some `frame-set-background-mode' rigmarole + ;; by assigning the new background immediately. + (let* ((settings (get theme 'theme-settings)) + (tail settings) + found) + (while (and tail (not found)) + (and (eq (nth 0 (car tail)) 'theme-face) + (eq (nth 1 (car tail)) 'default) + (setq found (car tail))) + (setq tail (cdr tail))) + (when found + (put theme 'theme-settings (cons found (delq found settings))))) + ;; Finally, enable the theme. + (unless no-enable + (enable-theme theme)) + t) (defun custom-theme-load-confirm (hash) "Query the user about loading a Custom theme that may not be safe. -- 2.17.1 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #3: 0002-Disable-no-byte-compile-in-built-in-themes.patch --] [-- Type: text/x-diff, Size: 6291 bytes --] From b560ca9d2c94af2d4af5513ac6f9dffa7d51c1ae Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Wed, 9 May 2018 22:30:48 +0100 Subject: [PATCH 2/8] Disable no-byte-compile in built-in themes * etc/themes/adwaita-theme.el: * etc/themes/deeper-blue-theme.el: * etc/themes/dichromacy-theme.el: * etc/themes/leuven-theme.el: * etc/themes/light-blue-theme.el: * etc/themes/manoj-dark-theme.el: * etc/themes/misterioso-theme.el: * etc/themes/tango-dark-theme.el: * etc/themes/tango-theme.el: * etc/themes/tsdh-dark-theme.el: * etc/themes/tsdh-light-theme.el: * etc/themes/wheatgrass-theme.el: * etc/themes/whiteboard-theme.el: * etc/themes/wombat-theme.el: Disable no-byte-compile. https://lists.gnu.org/archive/html/emacs-devel/2018-01/msg00614.html https://lists.gnu.org/archive/html/emacs-devel/2018-02/msg00060.html --- etc/themes/adwaita-theme.el | 4 ---- etc/themes/deeper-blue-theme.el | 4 ---- etc/themes/dichromacy-theme.el | 4 ---- etc/themes/leuven-theme.el | 1 - etc/themes/light-blue-theme.el | 4 ---- etc/themes/manoj-dark-theme.el | 4 ---- etc/themes/misterioso-theme.el | 4 ---- etc/themes/tango-dark-theme.el | 4 ---- etc/themes/tango-theme.el | 4 ---- etc/themes/tsdh-dark-theme.el | 4 ---- etc/themes/tsdh-light-theme.el | 5 ----- etc/themes/wheatgrass-theme.el | 4 ---- etc/themes/whiteboard-theme.el | 4 ---- etc/themes/wombat-theme.el | 4 ---- 14 files changed, 54 deletions(-) diff --git a/etc/themes/adwaita-theme.el b/etc/themes/adwaita-theme.el index b376153510..415db8a191 100644 --- a/etc/themes/adwaita-theme.el +++ b/etc/themes/adwaita-theme.el @@ -99,8 +99,4 @@ adwaita `(diff-added ((,class (:bold t :foreground "#4E9A06")))) `(diff-removed ((,class (:bold t :foreground "#F5666D")))))) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; adwaita-theme.el ends here diff --git a/etc/themes/deeper-blue-theme.el b/etc/themes/deeper-blue-theme.el index c6aa1751f4..0700f4f23d 100644 --- a/etc/themes/deeper-blue-theme.el +++ b/etc/themes/deeper-blue-theme.el @@ -110,8 +110,4 @@ deeper-blue (provide-theme 'deeper-blue) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; deeper-blue-theme.el ends here diff --git a/etc/themes/dichromacy-theme.el b/etc/themes/dichromacy-theme.el index 793209c055..bfced43aee 100644 --- a/etc/themes/dichromacy-theme.el +++ b/etc/themes/dichromacy-theme.el @@ -122,8 +122,4 @@ dichromacy (provide-theme 'dichromacy) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; dichromacy-theme.el ends here diff --git a/etc/themes/leuven-theme.el b/etc/themes/leuven-theme.el index 5c0d19ce81..c3c666588b 100644 --- a/etc/themes/leuven-theme.el +++ b/etc/themes/leuven-theme.el @@ -708,7 +708,6 @@ leuven ;; time-stamp-format: "%:y%02m%02d.%02H%02M" ;; time-stamp-start: "Version: " ;; time-stamp-end: "$" -;; no-byte-compile: t ;; End: ;;; leuven-theme.el ends here diff --git a/etc/themes/light-blue-theme.el b/etc/themes/light-blue-theme.el index 9935c565fb..ba00db6a49 100644 --- a/etc/themes/light-blue-theme.el +++ b/etc/themes/light-blue-theme.el @@ -61,8 +61,4 @@ light-blue (provide-theme 'light-blue) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; light-blue-theme.el ends here diff --git a/etc/themes/manoj-dark-theme.el b/etc/themes/manoj-dark-theme.el index fe61441d78..ddcaa0bd99 100644 --- a/etc/themes/manoj-dark-theme.el +++ b/etc/themes/manoj-dark-theme.el @@ -700,8 +700,4 @@ manoj-dark (provide-theme 'manoj-dark) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; manoj-dark.el ends here diff --git a/etc/themes/misterioso-theme.el b/etc/themes/misterioso-theme.el index 42e448d28b..6c1eec0f42 100644 --- a/etc/themes/misterioso-theme.el +++ b/etc/themes/misterioso-theme.el @@ -103,8 +103,4 @@ misterioso (provide-theme 'misterioso) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; misterioso-theme.el ends here diff --git a/etc/themes/tango-dark-theme.el b/etc/themes/tango-dark-theme.el index 3b6eeb702e..dae77a5e62 100644 --- a/etc/themes/tango-dark-theme.el +++ b/etc/themes/tango-dark-theme.el @@ -170,8 +170,4 @@ tango-dark (provide-theme 'tango-dark) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; tango-dark-theme.el ends here diff --git a/etc/themes/tango-theme.el b/etc/themes/tango-theme.el index a7a79c04ad..4fe2480bc7 100644 --- a/etc/themes/tango-theme.el +++ b/etc/themes/tango-theme.el @@ -154,8 +154,4 @@ tango (provide-theme 'tango) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; tango-theme.el ends here diff --git a/etc/themes/tsdh-dark-theme.el b/etc/themes/tsdh-dark-theme.el index 287fef8253..c216750cb2 100644 --- a/etc/themes/tsdh-dark-theme.el +++ b/etc/themes/tsdh-dark-theme.el @@ -144,8 +144,4 @@ tsdh-dark (provide-theme 'tsdh-dark) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; tsdh-dark-theme.el ends here diff --git a/etc/themes/tsdh-light-theme.el b/etc/themes/tsdh-light-theme.el index 17a86fdbfe..ce9d1a2c3c 100644 --- a/etc/themes/tsdh-light-theme.el +++ b/etc/themes/tsdh-light-theme.el @@ -106,9 +106,4 @@ tsdh-light (provide-theme 'tsdh-light) - -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; tsdh-light-theme.el ends here diff --git a/etc/themes/wheatgrass-theme.el b/etc/themes/wheatgrass-theme.el index 9585e3aa6e..8d34c28bf4 100644 --- a/etc/themes/wheatgrass-theme.el +++ b/etc/themes/wheatgrass-theme.el @@ -83,8 +83,4 @@ wheatgrass (provide-theme 'wheatgrass) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; wheatgrass-theme.el ends here diff --git a/etc/themes/whiteboard-theme.el b/etc/themes/whiteboard-theme.el index 5db0ddd68d..fe46cb0928 100644 --- a/etc/themes/whiteboard-theme.el +++ b/etc/themes/whiteboard-theme.el @@ -100,8 +100,4 @@ whiteboard (provide-theme 'whiteboard) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; whiteboard-theme.el ends here diff --git a/etc/themes/wombat-theme.el b/etc/themes/wombat-theme.el index 583b8dc3f6..00f29bb9fa 100644 --- a/etc/themes/wombat-theme.el +++ b/etc/themes/wombat-theme.el @@ -102,8 +102,4 @@ wombat (provide-theme 'wombat) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; wombat-theme.el ends here -- 2.17.1 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #4: 0003-Fix-custom-available-themes-file-expansion.patch --] [-- Type: text/x-diff, Size: 6746 bytes --] From 23f66699032a1e1c1bab496731cedfffaf71cc6d Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Mon, 4 Jun 2018 02:12:33 +0100 Subject: [PATCH 3/8] Fix custom-available-themes file expansion For discussion, see thread starting at https://lists.gnu.org/archive/html/emacs-devel/2018-05/msg00222.html. * lisp/custom.el: (custom-available-themes): Use directory-files instead of performing arbitrary wildcard expansion in file names. (custom-theme--load-path): Document return value. * test/lisp/custom-tests.el: New file. (custom-theme--load-path): New test. --- lisp/custom.el | 26 +++++++----- test/lisp/custom-tests.el | 87 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 10 deletions(-) create mode 100644 test/lisp/custom-tests.el diff --git a/lisp/custom.el b/lisp/custom.el index 1fed5dce53..ea58d8cbb7 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -1299,19 +1299,25 @@ custom-available-themes loaded, and no effort is made to check that the files contain valid Custom themes. For a list of loaded themes, check the variable `custom-known-themes'." - (let (sym themes) + (let ((suffix "-theme\\.el\\'") + themes) (dolist (dir (custom-theme--load-path)) - (when (file-directory-p dir) - (dolist (file (file-expand-wildcards - (expand-file-name "*-theme.el" dir) t)) - (setq file (file-name-nondirectory file)) - (and (string-match "\\`\\(.+\\)-theme.el\\'" file) - (setq sym (intern (match-string 1 file))) - (custom-theme-name-valid-p sym) - (push sym themes))))) - (nreverse (delete-dups themes)))) + ;; `custom-theme--load-path' promises DIR exists and is a + ;; directory, but `custom.el' is loaded too early during + ;; bootstrap to use `cl-lib' macros, so guard with + ;; `file-directory-p' instead of calling `cl-assert'. + (dolist (file (and (file-directory-p dir) + (directory-files dir nil suffix))) + (let ((theme (intern (substring file 0 (string-match-p suffix file))))) + (and (custom-theme-name-valid-p theme) + (not (memq theme themes)) + (push theme themes))))) + (nreverse themes))) (defun custom-theme--load-path () + "Expand `custom-theme-load-path' into a list of directories. +Members of `custom-theme-load-path' that either don't exist or +are not directories are omitted from the expansion." (let (lpath) (dolist (f custom-theme-load-path) (cond ((eq f 'custom-theme-directory) diff --git a/test/lisp/custom-tests.el b/test/lisp/custom-tests.el new file mode 100644 index 0000000000..96887f8f5f --- /dev/null +++ b/test/lisp/custom-tests.el @@ -0,0 +1,87 @@ +;;; custom-tests.el --- tests for custom.el -*- lexical-binding: t -*- + +;; Copyright (C) 2018 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs 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. + +;; GNU Emacs 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 program. If not, see <https://www.gnu.org/licenses/>. + +;;; Code: + +(require 'ert) + +(ert-deftest custom-theme--load-path () + "Test `custom-theme--load-path' behavior." + (let ((tmpdir (file-name-as-directory (make-temp-file "custom-tests-" t)))) + (unwind-protect + ;; Create all temporary files under the same deletable parent. + (let ((temporary-file-directory tmpdir)) + ;; Path is empty. + (let ((custom-theme-load-path ())) + (should (null (custom-theme--load-path)))) + + ;; Path comprises non-existent file. + (let* ((name (make-temp-name tmpdir)) + (custom-theme-load-path (list name))) + (should (not (file-exists-p name))) + (should (null (custom-theme--load-path)))) + + ;; Path comprises existing file. + (let* ((file (make-temp-file "file")) + (custom-theme-load-path (list file))) + (should (file-exists-p file)) + (should (not (file-directory-p file))) + (should (null (custom-theme--load-path)))) + + ;; Path comprises existing directory. + (let* ((dir (make-temp-file "dir" t)) + (custom-theme-load-path (list dir))) + (should (file-directory-p dir)) + (should (equal (custom-theme--load-path) custom-theme-load-path))) + + ;; Expand `custom-theme-directory' path element. + (let ((custom-theme-load-path '(custom-theme-directory))) + (let ((custom-theme-directory (make-temp-name tmpdir))) + (should (not (file-exists-p custom-theme-directory))) + (should (null (custom-theme--load-path)))) + (let ((custom-theme-directory (make-temp-file "file"))) + (should (file-exists-p custom-theme-directory)) + (should (not (file-directory-p custom-theme-directory))) + (should (null (custom-theme--load-path)))) + (let ((custom-theme-directory (make-temp-file "dir" t))) + (should (file-directory-p custom-theme-directory)) + (should (equal (custom-theme--load-path) + (list custom-theme-directory))))) + + ;; Expand t path element. + (let ((custom-theme-load-path '(t))) + (let ((data-directory (make-temp-name tmpdir))) + (should (not (file-exists-p data-directory))) + (should (null (custom-theme--load-path)))) + (let ((data-directory tmpdir) + (themedir (expand-file-name "themes" tmpdir))) + (should (not (file-exists-p themedir))) + (should (null (custom-theme--load-path))) + (with-temp-file themedir) + (should (file-exists-p themedir)) + (should (not (file-directory-p themedir))) + (should (null (custom-theme--load-path))) + (delete-file themedir) + (make-directory themedir) + (should (file-directory-p themedir)) + (should (equal (custom-theme--load-path) (list themedir)))))) + (when (file-directory-p tmpdir) + (delete-directory tmpdir t))))) + +;;; custom-tests.el ends here -- 2.17.1 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #5: 0004-lisp-custom.el-Use-lexical-binding.patch --] [-- Type: text/x-diff, Size: 7797 bytes --] From 9ee1c5e2d734897298ebcd716cec4fad62d957ff Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Fri, 11 May 2018 16:09:57 +0100 Subject: [PATCH 4/8] * lisp/custom.el: Use lexical-binding Remove duplicate 'Custom Themes' comment heading. (deftheme, custom-declare-theme): Fix advertised calling convention. (custom-enabled-themes): Fix message grammar. --- lisp/custom.el | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/lisp/custom.el b/lisp/custom.el index ea58d8cbb7..f60d6d217f 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -1,4 +1,4 @@ -;;; custom.el --- tools for declaring and initializing options +;;; custom.el --- tools for declaring and initializing options -*- lexical-binding: t -*- ;; ;; Copyright (C) 1996-1997, 1999, 2001-2018 Free Software Foundation, ;; Inc. @@ -150,7 +150,7 @@ custom-declare-variable (put symbol 'force-value nil)) (if (keywordp doc) (error "Doc string is missing")) - (let ((initialize 'custom-initialize-reset) + (let ((initialize #'custom-initialize-reset) (requests nil)) (unless (memq :group args) (custom-add-to-group (custom-current-group) symbol 'custom-variable)) @@ -426,7 +426,7 @@ custom-current-group (defun custom-declare-group (symbol members doc &rest args) "Like `defgroup', but SYMBOL is evaluated as a normal argument." (while members - (apply 'custom-add-to-group symbol (car members)) + (apply #'custom-add-to-group symbol (car members)) (setq members (cdr members))) (when doc ;; This text doesn't get into DOC. @@ -618,11 +618,8 @@ custom-note-var-changed The result is that the change is treated as having been made through Custom." (put variable 'customized-value (list (custom-quote (eval variable))))) -\f -;;; Custom Themes - -;;; Loading files needed to customize a symbol. -;;; This is in custom.el because menu-bar.el needs it for toggle cmds. +;; Loading files needed to customize a symbol. +;; This is in custom.el because menu-bar.el needs it for toggle cmds. (defvar custom-load-recursion nil "Hack to avoid recursive dependencies.") @@ -715,7 +712,7 @@ customize-mark-to-save Return non-nil if the `saved-value' property actually changed." (custom-load-symbol symbol) - (let* ((get (or (get symbol 'custom-get) 'default-value)) + (let* ((get (or (get symbol 'custom-get) #'default-value)) (value (funcall get symbol)) (saved (get symbol 'saved-value)) (standard (get symbol 'standard-value)) @@ -744,7 +741,7 @@ customize-mark-as-set Return non-nil if the `customized-value' property actually changed." (custom-load-symbol symbol) - (let* ((get (or (get symbol 'custom-get) 'default-value)) + (let* ((get (or (get symbol 'custom-get) #'default-value)) (value (funcall get symbol)) (customized (get symbol 'customized-value)) (old (or (get symbol 'saved-value) (get symbol 'standard-value)))) @@ -776,7 +773,7 @@ custom-reevaluate-setting ;; always do the funcall step, even if symbol was not bound before. (or (default-boundp symbol) (eval `(defvar ,symbol nil))) ; reset below, so any value is fine - (funcall (or (get symbol 'custom-set) 'set-default) + (funcall (or (get symbol 'custom-set) #'set-default) symbol (eval (car (or (get symbol 'saved-value) (get symbol 'standard-value)))))) @@ -941,7 +938,7 @@ custom-set-variables REQUEST is a list of features we must require in order to handle SYMBOL properly. COMMENT is a comment string about SYMBOL." - (apply 'custom-theme-set-variables 'user args)) + (apply #'custom-theme-set-variables 'user args)) (defun custom-theme-set-variables (theme &rest args) "Initialize variables for theme THEME according to settings in ARGS. @@ -989,8 +986,8 @@ custom-theme-set-variables set) (when requests (put symbol 'custom-requests requests) - (mapc 'require requests)) - (setq set (or (get symbol 'custom-set) 'custom-set-default)) + (mapc #'require requests)) + (setq set (or (get symbol 'custom-set) #'custom-set-default)) (put symbol 'saved-value (list value)) (put symbol 'saved-variable-comment comment) ;; Allow for errors in the case where the setter has @@ -1086,26 +1083,29 @@ custom--sort-vars-1 ;; they were used to supply keyword-value pairs like `:immediate', ;; `:variable-reset-string', etc. We don't use any of these, so ignore them. -(defmacro deftheme (theme &optional doc &rest ignored) +(defmacro deftheme (theme &optional doc &rest _ignored) "Declare THEME to be a Custom theme. The optional argument DOC is a doc string describing the theme. Any theme `foo' should be defined in a file called `foo-theme.el'; see `custom-make-theme-feature' for more information." - (declare (doc-string 2)) + (declare (doc-string 2) + (advertised-calling-convention (theme &optional doc) "22.1")) (let ((feature (custom-make-theme-feature theme))) ;; It is better not to use backquote in this file, ;; because that makes a bootstrapping problem ;; if you need to recompile all the Lisp files using interpreted code. (list 'custom-declare-theme (list 'quote theme) (list 'quote feature) doc))) -(defun custom-declare-theme (theme feature &optional doc &rest ignored) +(defun custom-declare-theme (theme feature &optional doc &rest _ignored) "Like `deftheme', but THEME is evaluated as a normal argument. FEATURE is the feature this theme provides. Normally, this is a symbol created from THEME by `custom-make-theme-feature'." + (declare (advertised-calling-convention (theme feature &optional doc) "22.1")) (unless (custom-theme-name-valid-p theme) (error "Custom theme cannot be named %S" theme)) - (add-to-list 'custom-known-themes theme) + (unless (memq theme custom-known-themes) + (push theme custom-known-themes)) (put theme 'theme-feature feature) (when doc (put theme 'theme-documentation doc))) @@ -1206,7 +1206,7 @@ load-theme (interactive (list (intern (completing-read "Load custom theme: " - (mapcar 'symbol-name + (mapcar #'symbol-name (custom-available-themes)))) nil nil)) (unless (custom-theme-name-valid-p theme) @@ -1395,9 +1395,9 @@ custom-enabled-themes themes (delq theme themes))))) (enable-theme 'user) (custom-set-default symbol themes) - (if failures - (message "Failed to enable theme: %s" - (mapconcat 'symbol-name failures ", ")))))) + (when failures + (message "Failed to enable theme(s): %s" + (mapconcat #'symbol-name failures ", ")))))) (defsubst custom-theme-enabled-p (theme) "Return non-nil if THEME is enabled." @@ -1409,7 +1409,7 @@ disable-theme (interactive (list (intern (completing-read "Disable custom theme: " - (mapcar 'symbol-name custom-enabled-themes) + (mapcar #'symbol-name custom-enabled-themes) nil t)))) (when (custom-theme-enabled-p theme) (let ((settings (get theme 'theme-settings))) @@ -1475,7 +1475,7 @@ custom-theme-recalc-variable (if (and valspec (or (get variable 'force-value) (default-boundp variable))) - (funcall (or (get variable 'custom-set) 'set-default) variable + (funcall (or (get variable 'custom-set) #'set-default) variable (eval (car valspec)))))) (defun custom-theme-recalc-face (face) @@ -1516,7 +1516,7 @@ custom-reset-variables (VARIABLE IGNORED) This means reset VARIABLE. (The argument IGNORED is ignored)." - (apply 'custom-theme-reset-variables 'user args)) + (apply #'custom-theme-reset-variables 'user args)) ;;; The End. -- 2.17.1 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #6: 0005-lisp-cus-theme.el-Use-lexical-binding.patch --] [-- Type: text/x-diff, Size: 5907 bytes --] From 1afe0d64386e80904459ba8fa2dc6ec2931f0e9e Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Fri, 11 May 2018 15:35:09 +0100 Subject: [PATCH 5/8] * lisp/cus-theme.el: Use lexical-binding --- lisp/cus-theme.el | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/lisp/cus-theme.el b/lisp/cus-theme.el index e5e787771b..53389956ad 100644 --- a/lisp/cus-theme.el +++ b/lisp/cus-theme.el @@ -1,4 +1,4 @@ -;;; cus-theme.el -- custom theme creation user interface +;;; cus-theme.el -- custom theme creation user interface -*- lexical-binding: t -*- ;; ;; Copyright (C) 2001-2018 Free Software Foundation, Inc. ;; @@ -47,7 +47,7 @@ custom-new-theme-mode Do not call this mode function yourself. It is meant for internal use." (use-local-map custom-new-theme-mode-map) (custom--initialize-widget-variables) - (set (make-local-variable 'revert-buffer-function) 'custom-theme-revert)) + (set (make-local-variable 'revert-buffer-function) #'custom-theme-revert)) (put 'custom-new-theme-mode 'mode-class 'special) (defvar custom-theme-name nil) @@ -118,13 +118,13 @@ customize-create-theme :tag " Visit Theme " :help-echo "Insert the settings of a pre-defined theme." :action (lambda (_widget &optional _event) - (call-interactively 'custom-theme-visit-theme))) + (call-interactively #'custom-theme-visit-theme))) (widget-insert " ") (widget-create 'push-button :tag " Merge Theme " :help-echo "Merge in the settings of a pre-defined theme." :action (lambda (_widget &optional _event) - (call-interactively 'custom-theme-merge-theme))) + (call-interactively #'custom-theme-merge-theme))) (widget-insert " ") (widget-create 'push-button :tag " Revert " @@ -142,7 +142,7 @@ customize-create-theme (widget-create 'text :value (format-time-string "Created %Y-%m-%d."))) (widget-create 'push-button - :notify (function custom-theme-write) + :notify #'custom-theme-write " Save Theme ") (when (eq theme 'user) (setq custom-theme--migrate-settings t) @@ -188,7 +188,7 @@ customize-create-theme :mouse-face 'highlight :pressed-face 'highlight :action (lambda (_widget &optional _event) - (call-interactively 'custom-theme-add-face))) + (call-interactively #'custom-theme-add-face))) ;; If THEME is non-nil, insert all of that theme's variables. (widget-insert "\n\n Theme variables:\n ") @@ -207,7 +207,7 @@ customize-create-theme :mouse-face 'highlight :pressed-face 'highlight :action (lambda (_widget &optional _event) - (call-interactively 'custom-theme-add-variable))) + (call-interactively #'custom-theme-add-variable))) (widget-insert ?\n) (widget-setup) (goto-char (point-min)) @@ -254,7 +254,7 @@ custom-theme-add-var-1 :tag (custom-unlispify-tag-name symbol) :value symbol :shown-value (list val) - :notify 'ignore + :notify #'ignore :custom-level 0 :custom-state 'hidden :custom-style 'simple)) @@ -313,7 +313,7 @@ custom-theme-visit-theme (interactive (list (intern (completing-read "Find custom theme: " - (mapcar 'symbol-name + (mapcar #'symbol-name (custom-available-themes)))))) (unless (custom-theme-name-valid-p theme) (error "No valid theme named `%s'" theme)) @@ -328,7 +328,7 @@ custom-theme-merge-theme (interactive (list (intern (completing-read "Merge custom theme: " - (mapcar 'symbol-name + (mapcar #'symbol-name (custom-available-themes)))))) (unless (eq theme 'user) (unless (custom-theme-name-valid-p theme) @@ -343,8 +343,8 @@ custom-theme-merge-theme (memq name '(custom-enabled-themes custom-safe-themes))) (funcall (if option - 'custom-theme-add-variable - 'custom-theme-add-face) + #'custom-theme-add-variable + #'custom-theme-add-face) name value))))) theme) @@ -475,7 +475,7 @@ describe-theme (interactive (list (intern (completing-read "Describe custom theme: " - (mapcar 'symbol-name + (mapcar #'symbol-name (custom-available-themes)))))) (unless (custom-theme-name-valid-p theme) (error "Invalid theme name `%s'" theme)) @@ -616,11 +616,11 @@ customize-themes (widget-create 'push-button :tag " Save Theme Settings " :help-echo "Save the selected themes for future sessions." - :action 'custom-theme-save) + :action #'custom-theme-save) (widget-insert ?\n) (widget-create 'checkbox :value custom-theme-allow-multiple-selections - :action 'custom-theme-selections-toggle) + :action #'custom-theme-selections-toggle) (widget-insert (propertize " Select more than one theme at a time" 'face '(variable-pitch (:height 0.9)))) @@ -632,13 +632,13 @@ customize-themes :value (custom-theme-enabled-p theme) :theme-name theme :help-echo help-echo - :action 'custom-theme-checkbox-toggle)) + :action #'custom-theme-checkbox-toggle)) (push (cons theme widget) custom--listed-themes) (widget-create-child-and-convert widget 'push-button :button-face-get 'ignore :mouse-face-get 'ignore :value (format " %s" theme) - :action 'widget-parent-action + :action #'widget-parent-action :help-echo help-echo) (widget-insert " -- " (propertize (custom-theme-summary theme) -- 2.17.1 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #7: 0006-Minor-custom.el-simplifications.patch --] [-- Type: text/x-diff, Size: 7892 bytes --] From 48339577d2a4a4eee14fc2ae223fe3e59f93d239 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Thu, 31 May 2018 18:37:02 +0100 Subject: [PATCH 6/8] Minor custom.el simplifications * lisp/custom.el (custom-quote): Duplicate macroexp-quote. (custom-load-symbol, customize-mark-to-save, customize-mark-as-set) (custom-theme-name-valid-p, enable-theme, custom-enabled-themes) (disable-theme): Simplify logic. --- lisp/custom.el | 103 ++++++++++++++++++++++--------------------------- 1 file changed, 46 insertions(+), 57 deletions(-) diff --git a/lisp/custom.el b/lisp/custom.el index f60d6d217f..034d40eace 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -630,14 +630,12 @@ custom-load-symbol (let ((custom-load-recursion t)) ;; Load these files if not already done, ;; to make sure we know all the dependencies of SYMBOL. - (condition-case nil - (require 'cus-load) - (error nil)) - (condition-case nil - (require 'cus-start) - (error nil)) + (ignore-errors + (require 'cus-load)) + (ignore-errors + (require 'cus-start)) (dolist (load (get symbol 'custom-loads)) - (cond ((symbolp load) (condition-case nil (require load) (error nil))) + (cond ((symbolp load) (ignore-errors (require load))) ;; This is subsumed by the test below, but it's much faster. ((assoc load load-history)) ;; This was just (assoc (locate-library load) load-history) @@ -655,7 +653,7 @@ custom-load-symbol ;; We are still loading it when we call this, ;; and it is not in load-history yet. ((equal load "cus-edit")) - (t (condition-case nil (load load) (error nil)))))))) + (t (ignore-errors (load load)))))))) \f (defvar custom-local-buffer nil "Non-nil, in a Customization buffer, means customize a specific buffer. @@ -688,16 +686,12 @@ custom-set-minor-mode (defun custom-quote (sexp) "Quote SEXP if it is not self quoting." - (if (or (memq sexp '(t nil)) - (keywordp sexp) - (and (listp sexp) - (memq (car sexp) '(lambda))) - (stringp sexp) - (numberp sexp) - (vectorp sexp) -;;; (and (fboundp 'characterp) -;;; (characterp sexp)) - ) + ;; Can't use `macroexp-quote' because it is loaded after `custom.el' + ;; during bootstrap. See `loadup.el'. + (if (and (not (consp sexp)) + (or (keywordp sexp) + (not (symbolp sexp)) + (booleanp sexp))) sexp (list 'quote sexp))) @@ -718,12 +712,10 @@ customize-mark-to-save (standard (get symbol 'standard-value)) (comment (get symbol 'customized-variable-comment))) ;; Save default value if different from standard value. - (if (or (null standard) - (not (equal value (condition-case nil - (eval (car standard)) - (error nil))))) - (put symbol 'saved-value (list (custom-quote value))) - (put symbol 'saved-value nil)) + (put symbol 'saved-value + (unless (and standard + (equal value (ignore-errors (eval (car standard))))) + (list (custom-quote value)))) ;; Clear customized information (set, but not saved). (put symbol 'customized-value nil) ;; Save any comment that might have been set. @@ -747,9 +739,8 @@ customize-mark-as-set (old (or (get symbol 'saved-value) (get symbol 'standard-value)))) ;; Mark default value as set if different from old value. (if (not (and old - (equal value (condition-case nil - (eval (car old)) - (error nil))))) + (equal value (ignore-errors + (eval (car old)))))) (progn (put symbol 'customized-value (list (custom-quote value))) (custom-push-theme 'theme-value symbol 'user 'set (custom-quote value))) @@ -1284,11 +1275,9 @@ custom-theme-load-confirm (defun custom-theme-name-valid-p (name) "Return t if NAME is a valid name for a Custom theme, nil otherwise. NAME should be a symbol." - (and (symbolp name) - name - (not (or (zerop (length (symbol-name name))) - (eq name 'user) - (eq name 'changed))))) + (and (not (memq name '(nil user changed))) + (symbolp name) + (not (string= "" (symbol-name name))))) (defun custom-available-themes () "Return a list of Custom themes available for loading. @@ -1340,8 +1329,8 @@ enable-theme (completing-read "Enable custom theme: " obarray (lambda (sym) (get sym 'theme-settings)) t)))) - (if (not (custom-theme-p theme)) - (error "Undefined Custom theme %s" theme)) + (unless (custom-theme-p theme) + (error "Undefined Custom theme %s" theme)) (let ((settings (get theme 'theme-settings))) ;; Loop through theme settings, recalculating vars/faces. (dolist (s settings) @@ -1381,18 +1370,18 @@ custom-enabled-themes (let (failures) (setq themes (delq 'user (delete-dups themes))) ;; Disable all themes not in THEMES. - (if (boundp symbol) - (dolist (theme (symbol-value symbol)) - (if (not (memq theme themes)) - (disable-theme theme)))) + (dolist (theme (and (boundp symbol) + (symbol-value symbol))) + (unless (memq theme themes) + (disable-theme theme))) ;; Call `enable-theme' or `load-theme' on each of THEMES. (dolist (theme (reverse themes)) (condition-case nil (if (custom-theme-p theme) (enable-theme theme) (load-theme theme)) - (error (setq failures (cons theme failures) - themes (delq theme themes))))) + (error (push theme failures) + (setq themes (delq theme themes))))) (enable-theme 'user) (custom-set-default symbol themes) (when failures @@ -1425,23 +1414,23 @@ disable-theme ;; If the face spec specified by this theme is in the ;; saved-face property, reset that property. (when (equal (nth 3 s) (get symbol 'saved-face)) - (put symbol 'saved-face (and val (cadr (car val))))))))) - ;; Recompute faces on all frames. - (dolist (frame (frame-list)) - ;; We must reset the fg and bg color frame parameters, or - ;; `face-set-after-frame-default' will use the existing - ;; parameters, which could be from the disabled theme. - (set-frame-parameter frame 'background-color - (custom--frame-color-default - frame :background "background" "Background" - "unspecified-bg" "white")) - (set-frame-parameter frame 'foreground-color - (custom--frame-color-default - frame :foreground "foreground" "Foreground" - "unspecified-fg" "black")) - (face-set-after-frame-default frame)) - (setq custom-enabled-themes - (delq theme custom-enabled-themes))))) + (put symbol 'saved-face (cadar val)))))))) + ;; Recompute faces on all frames. + (dolist (frame (frame-list)) + ;; We must reset the fg and bg color frame parameters, or + ;; `face-set-after-frame-default' will use the existing + ;; parameters, which could be from the disabled theme. + (set-frame-parameter frame 'background-color + (custom--frame-color-default + frame :background "background" "Background" + "unspecified-bg" "white")) + (set-frame-parameter frame 'foreground-color + (custom--frame-color-default + frame :foreground "foreground" "Foreground" + "unspecified-fg" "black")) + (face-set-after-frame-default frame)) + (setq custom-enabled-themes + (delq theme custom-enabled-themes)))) ;; Only used if window-system not null. (declare-function x-get-resource "frame.c" -- 2.17.1 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #8: 0007-Minor-cus-theme.el-simplifications.patch --] [-- Type: text/x-diff, Size: 3932 bytes --] From ee62af507c85193266b656c5ac7811600eba2a10 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Thu, 10 May 2018 03:08:10 +0100 Subject: [PATCH 7/8] Minor cus-theme.el simplifications * lisp/cus-theme.el (custom-new-theme-mode, customize-themes) (custom-theme-choose-mode): Use setq-local. (customize-create-theme): Ditto. Use delete-all-overlays. (describe-theme-1, custom-theme-summary): Simplify logic. --- lisp/cus-theme.el | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/lisp/cus-theme.el b/lisp/cus-theme.el index 53389956ad..995c55b2b2 100644 --- a/lisp/cus-theme.el +++ b/lisp/cus-theme.el @@ -47,7 +47,7 @@ custom-new-theme-mode Do not call this mode function yourself. It is meant for internal use." (use-local-map custom-new-theme-mode-map) (custom--initialize-widget-variables) - (set (make-local-variable 'revert-buffer-function) #'custom-theme-revert)) + (setq-local revert-buffer-function #'custom-theme-revert)) (put 'custom-new-theme-mode 'mode-class 'special) (defvar custom-theme-name nil) @@ -93,15 +93,14 @@ customize-create-theme (switch-to-buffer (get-buffer-create (or buffer "*Custom Theme*"))) (let ((inhibit-read-only t)) (erase-buffer) - (dolist (ov (overlays-in (point-min) (point-max))) - (delete-overlay ov))) + (delete-all-overlays)) (custom-new-theme-mode) (make-local-variable 'custom-theme-name) - (set (make-local-variable 'custom-theme--save-name) theme) - (set (make-local-variable 'custom-theme-faces) nil) - (set (make-local-variable 'custom-theme-variables) nil) - (set (make-local-variable 'custom-theme-description) "") - (set (make-local-variable 'custom-theme--migrate-settings) nil) + (setq-local custom-theme--save-name theme) + (setq-local custom-theme-faces nil) + (setq-local custom-theme-variables nil) + (setq-local custom-theme-description "") + (setq-local custom-theme--migrate-settings nil) (make-local-variable 'custom-theme-insert-face-marker) (make-local-variable 'custom-theme-insert-variable-marker) (make-local-variable 'custom-theme--listed-faces) @@ -513,8 +512,7 @@ describe-theme-1 (condition-case nil (read (current-buffer)) (end-of-file nil))))) - (and sexp (listp sexp) - (eq (car sexp) 'deftheme) + (and (eq (car-safe sexp) 'deftheme) (setq doc (nth 2 sexp))))))) (princ "\n\nDocumentation:\n") (princ (if (stringp doc) @@ -552,10 +550,10 @@ custom-theme-choose-mode Do not call this mode function yourself. It is meant for internal use." (use-local-map custom-theme-choose-mode-map) (custom--initialize-widget-variables) - (set (make-local-variable 'revert-buffer-function) - (lambda (_ignore-auto noconfirm) - (when (or noconfirm (y-or-n-p "Discard current choices? ")) - (customize-themes (current-buffer)))))) + (setq-local revert-buffer-function + (lambda (_ignore-auto noconfirm) + (when (or noconfirm (y-or-n-p "Discard current choices? ")) + (customize-themes (current-buffer)))))) (put 'custom-theme-choose-mode 'mode-class 'special) ;;;###autoload @@ -568,7 +566,7 @@ customize-themes (let ((inhibit-read-only t)) (erase-buffer)) (custom-theme-choose-mode) - (set (make-local-variable 'custom--listed-themes) nil) + (setq-local custom--listed-themes nil) (make-local-variable 'custom-theme-allow-multiple-selections) (and (null custom-theme-allow-multiple-selections) (> (length custom-enabled-themes) 1) @@ -662,8 +660,7 @@ custom-theme-summary (condition-case nil (read (current-buffer)) (end-of-file nil))))) - (and sexp (listp sexp) - (eq (car sexp) 'deftheme) + (and (eq (car-safe sexp) 'deftheme) (setq doc (nth 2 sexp)))))))) (cond ((null doc) "(no documentation available)") -- 2.17.1 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #9: 0008-Tweak-subr-x.el-substring-functions.patch --] [-- Type: text/x-diff, Size: 4709 bytes --] From 96b4a9219633f9b37d7f101b72b9475b4f3a20a7 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Fri, 1 Jun 2018 21:58:10 +0100 Subject: [PATCH 8/8] Tweak subr-x.el substring functions * lisp/emacs-lisp/subr-x.el (string-join): #'-quote function symbol. (string-trim-left, string-trim-right): Make better use of substring for minor speedup. * test/lisp/emacs-lisp/subr-x-tests.el (subr-x-test-string-trim-left, subr-x-test-string-trim-right) (subr-x-test-string-remove-prefix) (subr-x-test-string-remove-suffix): New tests. --- lisp/emacs-lisp/subr-x.el | 12 +++---- test/lisp/emacs-lisp/subr-x-tests.el | 47 ++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el index 7fab9083e8..eb3ec85ecc 100644 --- a/lisp/emacs-lisp/subr-x.el +++ b/lisp/emacs-lisp/subr-x.el @@ -211,7 +211,7 @@ string-empty-p (defsubst string-join (strings &optional separator) "Join all STRINGS using SEPARATOR." - (mapconcat 'identity strings separator)) + (mapconcat #'identity strings separator)) (define-obsolete-function-alias 'string-reverse 'reverse "25.1") @@ -219,17 +219,17 @@ string-trim-left "Trim STRING of leading string matching REGEXP. REGEXP defaults to \"[ \\t\\n\\r]+\"." - (if (string-match (concat "\\`\\(?:" (or regexp "[ \t\n\r]+")"\\)") string) - (replace-match "" t t string) + (if (string-match (concat "\\`\\(?:" (or regexp "[ \t\n\r]+") "\\)") string) + (substring string (match-end 0)) string)) (defsubst string-trim-right (string &optional regexp) "Trim STRING of trailing string matching REGEXP. REGEXP defaults to \"[ \\t\\n\\r]+\"." - (if (string-match (concat "\\(?:" (or regexp "[ \t\n\r]+") "\\)\\'") string) - (replace-match "" t t string) - string)) + (let ((i (string-match-p (concat "\\(?:" (or regexp "[ \t\n\r]+") "\\)\\'") + string))) + (if i (substring string 0 i) string))) (defsubst string-trim (string &optional trim-left trim-right) "Trim STRING of leading and trailing strings matching TRIM-LEFT and TRIM-RIGHT. diff --git a/test/lisp/emacs-lisp/subr-x-tests.el b/test/lisp/emacs-lisp/subr-x-tests.el index f7f0ef384f..81467bab2d 100644 --- a/test/lisp/emacs-lisp/subr-x-tests.el +++ b/test/lisp/emacs-lisp/subr-x-tests.el @@ -532,6 +532,53 @@ (format "abs sum is: %s")) "abs sum is: 15"))) +\f +;; Substring tests + +(ert-deftest subr-x-test-string-trim-left () + "Test `string-trim-left' behavior." + (should (equal (string-trim-left "") "")) + (should (equal (string-trim-left " \t\n\r") "")) + (should (equal (string-trim-left " \t\n\ra") "a")) + (should (equal (string-trim-left "a \t\n\r") "a \t\n\r")) + (should (equal (string-trim-left "" "") "")) + (should (equal (string-trim-left "a" "") "a")) + (should (equal (string-trim-left "aa" "a*") "")) + (should (equal (string-trim-left "ba" "a*") "ba")) + (should (equal (string-trim-left "aa" "a*?") "aa")) + (should (equal (string-trim-left "aa" "a+?") "a"))) + +(ert-deftest subr-x-test-string-trim-right () + "Test `string-trim-right' behavior." + (should (equal (string-trim-right "") "")) + (should (equal (string-trim-right " \t\n\r") "")) + (should (equal (string-trim-right " \t\n\ra") " \t\n\ra")) + (should (equal (string-trim-right "a \t\n\r") "a")) + (should (equal (string-trim-right "" "") "")) + (should (equal (string-trim-right "a" "") "a")) + (should (equal (string-trim-right "aa" "a*") "")) + (should (equal (string-trim-right "ab" "a*") "ab")) + (should (equal (string-trim-right "aa" "a*?") ""))) + +(ert-deftest subr-x-test-string-remove-prefix () + "Test `string-remove-prefix' behavior." + (should (equal (string-remove-prefix "" "") "")) + (should (equal (string-remove-prefix "" "a") "a")) + (should (equal (string-remove-prefix "a" "") "")) + (should (equal (string-remove-prefix "a" "b") "b")) + (should (equal (string-remove-prefix "a" "a") "")) + (should (equal (string-remove-prefix "a" "aa") "a")) + (should (equal (string-remove-prefix "a" "ab") "b"))) + +(ert-deftest subr-x-test-string-remove-suffix () + "Test `string-remove-suffix' behavior." + (should (equal (string-remove-suffix "" "") "")) + (should (equal (string-remove-suffix "" "a") "a")) + (should (equal (string-remove-suffix "a" "") "")) + (should (equal (string-remove-suffix "a" "b") "b")) + (should (equal (string-remove-suffix "a" "a") "")) + (should (equal (string-remove-suffix "a" "aa") "a")) + (should (equal (string-remove-suffix "a" "ba") "b"))) (provide 'subr-x-tests) ;;; subr-x-tests.el ends here -- 2.17.1 ^ permalink raw reply related [flat|nested] 33+ messages in thread
* Re: Byte-compilation of custom themes 2018-06-04 1:33 ` Basil L. Contovounesios @ 2018-07-03 7:57 ` Basil L. Contovounesios 2018-07-11 1:40 ` Stefan Monnier 0 siblings, 1 reply; 33+ messages in thread From: Basil L. Contovounesios @ 2018-07-03 7:57 UTC (permalink / raw To: Stefan Monnier; +Cc: Eli Zaretskii, emacs-devel [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: 0001-Improve-loading-of-byte-compiled-custom-themes.patch --] [-- Type: text/x-diff, Size: 4290 bytes --] From d3c87ab44e78c24c7f2e20f343e9df2a92cd3354 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Wed, 9 May 2018 22:20:47 +0100 Subject: [PATCH 1/8] Improve loading of byte-compiled custom themes * lisp/custom.el (load-theme): Load byte-compiled file of safe themes when available. https://lists.gnu.org/archive/html/emacs-devel/2018-01/msg00614.html https://lists.gnu.org/archive/html/emacs-devel/2018-02/msg00060.html --- lisp/custom.el | 78 ++++++++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 37 deletions(-) diff --git a/lisp/custom.el b/lisp/custom.el index 4a778a0573..b8ea8811a2 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -1233,43 +1233,47 @@ load-theme (put theme 'theme-settings nil) (put theme 'theme-feature nil) (put theme 'theme-documentation nil)) - (let ((fn (locate-file (concat (symbol-name theme) "-theme.el") - (custom-theme--load-path) - '("" "c")))) - (unless fn - (error "Unable to find theme file for `%s'" theme)) - (with-temp-buffer - (insert-file-contents fn) - ;; Check file safety with `custom-safe-themes', prompting the - ;; user if necessary. - (when (or no-confirm - (eq custom-safe-themes t) - (and (memq 'default custom-safe-themes) - (equal (file-name-directory fn) - (expand-file-name "themes/" data-directory))) - (let ((hash (secure-hash 'sha256 (current-buffer)))) - (or (member hash custom-safe-themes) - (custom-theme-load-confirm hash)))) - (let ((custom--inhibit-theme-enable t) - (buffer-file-name fn)) ;For load-history. - (eval-buffer)) - ;; Optimization: if the theme changes the `default' face, put that - ;; entry first. This avoids some `frame-set-background-mode' rigmarole - ;; by assigning the new background immediately. - (let* ((settings (get theme 'theme-settings)) - (tail settings) - found) - (while (and tail (not found)) - (and (eq (nth 0 (car tail)) 'theme-face) - (eq (nth 1 (car tail)) 'default) - (setq found (car tail))) - (setq tail (cdr tail))) - (if found - (put theme 'theme-settings (cons found (delq found settings))))) - ;; Finally, enable the theme. - (unless no-enable - (enable-theme theme)) - t)))) + (let ((file (locate-file (concat (symbol-name theme) "-theme.el") + (custom-theme--load-path) + '("" "c"))) + (custom--inhibit-theme-enable t)) + ;; Check file safety with `custom-safe-themes', prompting the + ;; user if necessary. + (cond ((not file) + (error "Unable to find theme file for `%s'" theme)) + ((or no-confirm + (eq custom-safe-themes t) + (and (memq 'default custom-safe-themes) + (equal (file-name-directory file) + (expand-file-name "themes/" data-directory)))) + ;; Theme is safe; load byte-compiled version if available. + (load (file-name-sans-extension file) nil t nil t)) + ((with-temp-buffer + (insert-file-contents file) + (let ((hash (secure-hash 'sha256 (current-buffer)))) + (when (or (member hash custom-safe-themes) + (custom-theme-load-confirm hash)) + (eval-buffer nil nil file) + t)))) + (t + (error "Unable to load theme `%s'" theme)))) + ;; Optimization: if the theme changes the `default' face, put that + ;; entry first. This avoids some `frame-set-background-mode' rigmarole + ;; by assigning the new background immediately. + (let* ((settings (get theme 'theme-settings)) + (tail settings) + found) + (while (and tail (not found)) + (and (eq (nth 0 (car tail)) 'theme-face) + (eq (nth 1 (car tail)) 'default) + (setq found (car tail))) + (setq tail (cdr tail))) + (when found + (put theme 'theme-settings (cons found (delq found settings))))) + ;; Finally, enable the theme. + (unless no-enable + (enable-theme theme)) + t) (defun custom-theme-load-confirm (hash) "Query the user about loading a Custom theme that may not be safe. -- 2.18.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #2: 0002-Disable-no-byte-compile-in-built-in-themes.patch --] [-- Type: text/x-diff, Size: 6291 bytes --] From 79d06b99e9aedd2bebaa2dff39157f50feacc474 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Wed, 9 May 2018 22:30:48 +0100 Subject: [PATCH 2/8] Disable no-byte-compile in built-in themes * etc/themes/adwaita-theme.el: * etc/themes/deeper-blue-theme.el: * etc/themes/dichromacy-theme.el: * etc/themes/leuven-theme.el: * etc/themes/light-blue-theme.el: * etc/themes/manoj-dark-theme.el: * etc/themes/misterioso-theme.el: * etc/themes/tango-dark-theme.el: * etc/themes/tango-theme.el: * etc/themes/tsdh-dark-theme.el: * etc/themes/tsdh-light-theme.el: * etc/themes/wheatgrass-theme.el: * etc/themes/whiteboard-theme.el: * etc/themes/wombat-theme.el: Disable no-byte-compile. https://lists.gnu.org/archive/html/emacs-devel/2018-01/msg00614.html https://lists.gnu.org/archive/html/emacs-devel/2018-02/msg00060.html --- etc/themes/adwaita-theme.el | 4 ---- etc/themes/deeper-blue-theme.el | 4 ---- etc/themes/dichromacy-theme.el | 4 ---- etc/themes/leuven-theme.el | 1 - etc/themes/light-blue-theme.el | 4 ---- etc/themes/manoj-dark-theme.el | 4 ---- etc/themes/misterioso-theme.el | 4 ---- etc/themes/tango-dark-theme.el | 4 ---- etc/themes/tango-theme.el | 4 ---- etc/themes/tsdh-dark-theme.el | 4 ---- etc/themes/tsdh-light-theme.el | 5 ----- etc/themes/wheatgrass-theme.el | 4 ---- etc/themes/whiteboard-theme.el | 4 ---- etc/themes/wombat-theme.el | 4 ---- 14 files changed, 54 deletions(-) diff --git a/etc/themes/adwaita-theme.el b/etc/themes/adwaita-theme.el index b376153510..415db8a191 100644 --- a/etc/themes/adwaita-theme.el +++ b/etc/themes/adwaita-theme.el @@ -99,8 +99,4 @@ adwaita `(diff-added ((,class (:bold t :foreground "#4E9A06")))) `(diff-removed ((,class (:bold t :foreground "#F5666D")))))) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; adwaita-theme.el ends here diff --git a/etc/themes/deeper-blue-theme.el b/etc/themes/deeper-blue-theme.el index c6aa1751f4..0700f4f23d 100644 --- a/etc/themes/deeper-blue-theme.el +++ b/etc/themes/deeper-blue-theme.el @@ -110,8 +110,4 @@ deeper-blue (provide-theme 'deeper-blue) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; deeper-blue-theme.el ends here diff --git a/etc/themes/dichromacy-theme.el b/etc/themes/dichromacy-theme.el index 793209c055..bfced43aee 100644 --- a/etc/themes/dichromacy-theme.el +++ b/etc/themes/dichromacy-theme.el @@ -122,8 +122,4 @@ dichromacy (provide-theme 'dichromacy) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; dichromacy-theme.el ends here diff --git a/etc/themes/leuven-theme.el b/etc/themes/leuven-theme.el index 5c0d19ce81..c3c666588b 100644 --- a/etc/themes/leuven-theme.el +++ b/etc/themes/leuven-theme.el @@ -708,7 +708,6 @@ leuven ;; time-stamp-format: "%:y%02m%02d.%02H%02M" ;; time-stamp-start: "Version: " ;; time-stamp-end: "$" -;; no-byte-compile: t ;; End: ;;; leuven-theme.el ends here diff --git a/etc/themes/light-blue-theme.el b/etc/themes/light-blue-theme.el index 9935c565fb..ba00db6a49 100644 --- a/etc/themes/light-blue-theme.el +++ b/etc/themes/light-blue-theme.el @@ -61,8 +61,4 @@ light-blue (provide-theme 'light-blue) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; light-blue-theme.el ends here diff --git a/etc/themes/manoj-dark-theme.el b/etc/themes/manoj-dark-theme.el index fe61441d78..ddcaa0bd99 100644 --- a/etc/themes/manoj-dark-theme.el +++ b/etc/themes/manoj-dark-theme.el @@ -700,8 +700,4 @@ manoj-dark (provide-theme 'manoj-dark) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; manoj-dark.el ends here diff --git a/etc/themes/misterioso-theme.el b/etc/themes/misterioso-theme.el index 42e448d28b..6c1eec0f42 100644 --- a/etc/themes/misterioso-theme.el +++ b/etc/themes/misterioso-theme.el @@ -103,8 +103,4 @@ misterioso (provide-theme 'misterioso) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; misterioso-theme.el ends here diff --git a/etc/themes/tango-dark-theme.el b/etc/themes/tango-dark-theme.el index 3b6eeb702e..dae77a5e62 100644 --- a/etc/themes/tango-dark-theme.el +++ b/etc/themes/tango-dark-theme.el @@ -170,8 +170,4 @@ tango-dark (provide-theme 'tango-dark) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; tango-dark-theme.el ends here diff --git a/etc/themes/tango-theme.el b/etc/themes/tango-theme.el index a7a79c04ad..4fe2480bc7 100644 --- a/etc/themes/tango-theme.el +++ b/etc/themes/tango-theme.el @@ -154,8 +154,4 @@ tango (provide-theme 'tango) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; tango-theme.el ends here diff --git a/etc/themes/tsdh-dark-theme.el b/etc/themes/tsdh-dark-theme.el index 287fef8253..c216750cb2 100644 --- a/etc/themes/tsdh-dark-theme.el +++ b/etc/themes/tsdh-dark-theme.el @@ -144,8 +144,4 @@ tsdh-dark (provide-theme 'tsdh-dark) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; tsdh-dark-theme.el ends here diff --git a/etc/themes/tsdh-light-theme.el b/etc/themes/tsdh-light-theme.el index 17a86fdbfe..ce9d1a2c3c 100644 --- a/etc/themes/tsdh-light-theme.el +++ b/etc/themes/tsdh-light-theme.el @@ -106,9 +106,4 @@ tsdh-light (provide-theme 'tsdh-light) - -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; tsdh-light-theme.el ends here diff --git a/etc/themes/wheatgrass-theme.el b/etc/themes/wheatgrass-theme.el index 9585e3aa6e..8d34c28bf4 100644 --- a/etc/themes/wheatgrass-theme.el +++ b/etc/themes/wheatgrass-theme.el @@ -83,8 +83,4 @@ wheatgrass (provide-theme 'wheatgrass) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; wheatgrass-theme.el ends here diff --git a/etc/themes/whiteboard-theme.el b/etc/themes/whiteboard-theme.el index 5db0ddd68d..fe46cb0928 100644 --- a/etc/themes/whiteboard-theme.el +++ b/etc/themes/whiteboard-theme.el @@ -100,8 +100,4 @@ whiteboard (provide-theme 'whiteboard) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; whiteboard-theme.el ends here diff --git a/etc/themes/wombat-theme.el b/etc/themes/wombat-theme.el index 583b8dc3f6..00f29bb9fa 100644 --- a/etc/themes/wombat-theme.el +++ b/etc/themes/wombat-theme.el @@ -102,8 +102,4 @@ wombat (provide-theme 'wombat) -;; Local Variables: -;; no-byte-compile: t -;; End: - ;;; wombat-theme.el ends here -- 2.18.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #3: 0003-Fix-custom-available-themes-file-expansion.patch --] [-- Type: text/x-diff, Size: 6746 bytes --] From 6db2601d2082d949e44f15420a016e26f20745dd Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Mon, 4 Jun 2018 02:12:33 +0100 Subject: [PATCH 3/8] Fix custom-available-themes file expansion For discussion, see thread starting at https://lists.gnu.org/archive/html/emacs-devel/2018-05/msg00222.html. * lisp/custom.el: (custom-available-themes): Use directory-files instead of performing arbitrary wildcard expansion in file names. (custom-theme--load-path): Document return value. * test/lisp/custom-tests.el: New file. (custom-theme--load-path): New test. --- lisp/custom.el | 26 +++++++----- test/lisp/custom-tests.el | 87 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+), 10 deletions(-) create mode 100644 test/lisp/custom-tests.el diff --git a/lisp/custom.el b/lisp/custom.el index b8ea8811a2..4536788eb2 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -1311,19 +1311,25 @@ custom-available-themes loaded, and no effort is made to check that the files contain valid Custom themes. For a list of loaded themes, check the variable `custom-known-themes'." - (let (sym themes) + (let ((suffix "-theme\\.el\\'") + themes) (dolist (dir (custom-theme--load-path)) - (when (file-directory-p dir) - (dolist (file (file-expand-wildcards - (expand-file-name "*-theme.el" dir) t)) - (setq file (file-name-nondirectory file)) - (and (string-match "\\`\\(.+\\)-theme.el\\'" file) - (setq sym (intern (match-string 1 file))) - (custom-theme-name-valid-p sym) - (push sym themes))))) - (nreverse (delete-dups themes)))) + ;; `custom-theme--load-path' promises DIR exists and is a + ;; directory, but `custom.el' is loaded too early during + ;; bootstrap to use `cl-lib' macros, so guard with + ;; `file-directory-p' instead of calling `cl-assert'. + (dolist (file (and (file-directory-p dir) + (directory-files dir nil suffix))) + (let ((theme (intern (substring file 0 (string-match-p suffix file))))) + (and (custom-theme-name-valid-p theme) + (not (memq theme themes)) + (push theme themes))))) + (nreverse themes))) (defun custom-theme--load-path () + "Expand `custom-theme-load-path' into a list of directories. +Members of `custom-theme-load-path' that either don't exist or +are not directories are omitted from the expansion." (let (lpath) (dolist (f custom-theme-load-path) (cond ((eq f 'custom-theme-directory) diff --git a/test/lisp/custom-tests.el b/test/lisp/custom-tests.el new file mode 100644 index 0000000000..96887f8f5f --- /dev/null +++ b/test/lisp/custom-tests.el @@ -0,0 +1,87 @@ +;;; custom-tests.el --- tests for custom.el -*- lexical-binding: t -*- + +;; Copyright (C) 2018 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; GNU Emacs 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. + +;; GNU Emacs 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 program. If not, see <https://www.gnu.org/licenses/>. + +;;; Code: + +(require 'ert) + +(ert-deftest custom-theme--load-path () + "Test `custom-theme--load-path' behavior." + (let ((tmpdir (file-name-as-directory (make-temp-file "custom-tests-" t)))) + (unwind-protect + ;; Create all temporary files under the same deletable parent. + (let ((temporary-file-directory tmpdir)) + ;; Path is empty. + (let ((custom-theme-load-path ())) + (should (null (custom-theme--load-path)))) + + ;; Path comprises non-existent file. + (let* ((name (make-temp-name tmpdir)) + (custom-theme-load-path (list name))) + (should (not (file-exists-p name))) + (should (null (custom-theme--load-path)))) + + ;; Path comprises existing file. + (let* ((file (make-temp-file "file")) + (custom-theme-load-path (list file))) + (should (file-exists-p file)) + (should (not (file-directory-p file))) + (should (null (custom-theme--load-path)))) + + ;; Path comprises existing directory. + (let* ((dir (make-temp-file "dir" t)) + (custom-theme-load-path (list dir))) + (should (file-directory-p dir)) + (should (equal (custom-theme--load-path) custom-theme-load-path))) + + ;; Expand `custom-theme-directory' path element. + (let ((custom-theme-load-path '(custom-theme-directory))) + (let ((custom-theme-directory (make-temp-name tmpdir))) + (should (not (file-exists-p custom-theme-directory))) + (should (null (custom-theme--load-path)))) + (let ((custom-theme-directory (make-temp-file "file"))) + (should (file-exists-p custom-theme-directory)) + (should (not (file-directory-p custom-theme-directory))) + (should (null (custom-theme--load-path)))) + (let ((custom-theme-directory (make-temp-file "dir" t))) + (should (file-directory-p custom-theme-directory)) + (should (equal (custom-theme--load-path) + (list custom-theme-directory))))) + + ;; Expand t path element. + (let ((custom-theme-load-path '(t))) + (let ((data-directory (make-temp-name tmpdir))) + (should (not (file-exists-p data-directory))) + (should (null (custom-theme--load-path)))) + (let ((data-directory tmpdir) + (themedir (expand-file-name "themes" tmpdir))) + (should (not (file-exists-p themedir))) + (should (null (custom-theme--load-path))) + (with-temp-file themedir) + (should (file-exists-p themedir)) + (should (not (file-directory-p themedir))) + (should (null (custom-theme--load-path))) + (delete-file themedir) + (make-directory themedir) + (should (file-directory-p themedir)) + (should (equal (custom-theme--load-path) (list themedir)))))) + (when (file-directory-p tmpdir) + (delete-directory tmpdir t))))) + +;;; custom-tests.el ends here -- 2.18.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #4: 0004-lisp-custom.el-Use-lexical-binding.patch --] [-- Type: text/x-diff, Size: 7797 bytes --] From c160ae70cf26be48ff23dc5ebb700eb819df58c9 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Fri, 11 May 2018 16:09:57 +0100 Subject: [PATCH 4/8] * lisp/custom.el: Use lexical-binding Remove duplicate 'Custom Themes' comment heading. (deftheme, custom-declare-theme): Fix advertised calling convention. (custom-enabled-themes): Fix message grammar. --- lisp/custom.el | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/lisp/custom.el b/lisp/custom.el index 4536788eb2..1c667c8aa2 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -1,4 +1,4 @@ -;;; custom.el --- tools for declaring and initializing options +;;; custom.el --- tools for declaring and initializing options -*- lexical-binding: t -*- ;; ;; Copyright (C) 1996-1997, 1999, 2001-2018 Free Software Foundation, ;; Inc. @@ -150,7 +150,7 @@ custom-declare-variable (put symbol 'force-value nil)) (if (keywordp doc) (error "Doc string is missing")) - (let ((initialize 'custom-initialize-reset) + (let ((initialize #'custom-initialize-reset) (requests nil)) (unless (memq :group args) (custom-add-to-group (custom-current-group) symbol 'custom-variable)) @@ -426,7 +426,7 @@ custom-current-group (defun custom-declare-group (symbol members doc &rest args) "Like `defgroup', but SYMBOL is evaluated as a normal argument." (while members - (apply 'custom-add-to-group symbol (car members)) + (apply #'custom-add-to-group symbol (car members)) (setq members (cdr members))) (when doc ;; This text doesn't get into DOC. @@ -618,11 +618,8 @@ custom-note-var-changed The result is that the change is treated as having been made through Custom." (put variable 'customized-value (list (custom-quote (eval variable))))) -\f -;;; Custom Themes - -;;; Loading files needed to customize a symbol. -;;; This is in custom.el because menu-bar.el needs it for toggle cmds. +;; Loading files needed to customize a symbol. +;; This is in custom.el because menu-bar.el needs it for toggle cmds. (defvar custom-load-recursion nil "Hack to avoid recursive dependencies.") @@ -715,7 +712,7 @@ customize-mark-to-save Return non-nil if the `saved-value' property actually changed." (custom-load-symbol symbol) - (let* ((get (or (get symbol 'custom-get) 'default-value)) + (let* ((get (or (get symbol 'custom-get) #'default-value)) (value (funcall get symbol)) (saved (get symbol 'saved-value)) (standard (get symbol 'standard-value)) @@ -744,7 +741,7 @@ customize-mark-as-set Return non-nil if the `customized-value' property actually changed." (custom-load-symbol symbol) - (let* ((get (or (get symbol 'custom-get) 'default-value)) + (let* ((get (or (get symbol 'custom-get) #'default-value)) (value (funcall get symbol)) (customized (get symbol 'customized-value)) (old (or (get symbol 'saved-value) (get symbol 'standard-value)))) @@ -776,7 +773,7 @@ custom-reevaluate-setting ;; always do the funcall step, even if symbol was not bound before. (or (default-boundp symbol) (eval `(defvar ,symbol nil))) ; reset below, so any value is fine - (funcall (or (get symbol 'custom-set) 'set-default) + (funcall (or (get symbol 'custom-set) #'set-default) symbol (eval (car (or (get symbol 'saved-value) (get symbol 'standard-value)))))) @@ -946,7 +943,7 @@ custom-set-variables REQUEST is a list of features we must require in order to handle SYMBOL properly. COMMENT is a comment string about SYMBOL." - (apply 'custom-theme-set-variables 'user args)) + (apply #'custom-theme-set-variables 'user args)) (defun custom-theme-set-variables (theme &rest args) "Initialize variables for theme THEME according to settings in ARGS. @@ -994,8 +991,8 @@ custom-theme-set-variables set) (when requests (put symbol 'custom-requests requests) - (mapc 'require requests)) - (setq set (or (get symbol 'custom-set) 'custom-set-default)) + (mapc #'require requests)) + (setq set (or (get symbol 'custom-set) #'custom-set-default)) (put symbol 'saved-value (list value)) (put symbol 'saved-variable-comment comment) ;; Allow for errors in the case where the setter has @@ -1091,26 +1088,29 @@ custom--sort-vars-1 ;; they were used to supply keyword-value pairs like `:immediate', ;; `:variable-reset-string', etc. We don't use any of these, so ignore them. -(defmacro deftheme (theme &optional doc &rest ignored) +(defmacro deftheme (theme &optional doc &rest _ignored) "Declare THEME to be a Custom theme. The optional argument DOC is a doc string describing the theme. Any theme `foo' should be defined in a file called `foo-theme.el'; see `custom-make-theme-feature' for more information." - (declare (doc-string 2)) + (declare (doc-string 2) + (advertised-calling-convention (theme &optional doc) "22.1")) (let ((feature (custom-make-theme-feature theme))) ;; It is better not to use backquote in this file, ;; because that makes a bootstrapping problem ;; if you need to recompile all the Lisp files using interpreted code. (list 'custom-declare-theme (list 'quote theme) (list 'quote feature) doc))) -(defun custom-declare-theme (theme feature &optional doc &rest ignored) +(defun custom-declare-theme (theme feature &optional doc &rest _ignored) "Like `deftheme', but THEME is evaluated as a normal argument. FEATURE is the feature this theme provides. Normally, this is a symbol created from THEME by `custom-make-theme-feature'." + (declare (advertised-calling-convention (theme feature &optional doc) "22.1")) (unless (custom-theme-name-valid-p theme) (error "Custom theme cannot be named %S" theme)) - (add-to-list 'custom-known-themes theme) + (unless (memq theme custom-known-themes) + (push theme custom-known-themes)) (put theme 'theme-feature feature) (when doc (put theme 'theme-documentation doc))) @@ -1218,7 +1218,7 @@ load-theme (interactive (list (intern (completing-read "Load custom theme: " - (mapcar 'symbol-name + (mapcar #'symbol-name (custom-available-themes)))) nil nil)) (unless (custom-theme-name-valid-p theme) @@ -1411,9 +1411,9 @@ custom-enabled-themes themes (delq theme themes))))) (enable-theme 'user) (custom-set-default symbol themes) - (if failures - (message "Failed to enable theme: %s" - (mapconcat 'symbol-name failures ", ")))))) + (when failures + (message "Failed to enable theme(s): %s" + (mapconcat #'symbol-name failures ", ")))))) (defsubst custom-theme-enabled-p (theme) "Return non-nil if THEME is enabled." @@ -1425,7 +1425,7 @@ disable-theme (interactive (list (intern (completing-read "Disable custom theme: " - (mapcar 'symbol-name custom-enabled-themes) + (mapcar #'symbol-name custom-enabled-themes) nil t)))) (when (custom-theme-enabled-p theme) (let ((settings (get theme 'theme-settings))) @@ -1491,7 +1491,7 @@ custom-theme-recalc-variable (if (and valspec (or (get variable 'force-value) (default-boundp variable))) - (funcall (or (get variable 'custom-set) 'set-default) variable + (funcall (or (get variable 'custom-set) #'set-default) variable (eval (car valspec)))))) (defun custom-theme-recalc-face (face) @@ -1532,7 +1532,7 @@ custom-reset-variables (VARIABLE IGNORED) This means reset VARIABLE. (The argument IGNORED is ignored)." - (apply 'custom-theme-reset-variables 'user args)) + (apply #'custom-theme-reset-variables 'user args)) ;;; The End. -- 2.18.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #5: 0005-lisp-cus-theme.el-Use-lexical-binding.patch --] [-- Type: text/x-diff, Size: 5907 bytes --] From f0d70f5c4834ba5baff668ea2ee171eed7faea81 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Fri, 11 May 2018 15:35:09 +0100 Subject: [PATCH 5/8] * lisp/cus-theme.el: Use lexical-binding --- lisp/cus-theme.el | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/lisp/cus-theme.el b/lisp/cus-theme.el index e5e787771b..53389956ad 100644 --- a/lisp/cus-theme.el +++ b/lisp/cus-theme.el @@ -1,4 +1,4 @@ -;;; cus-theme.el -- custom theme creation user interface +;;; cus-theme.el -- custom theme creation user interface -*- lexical-binding: t -*- ;; ;; Copyright (C) 2001-2018 Free Software Foundation, Inc. ;; @@ -47,7 +47,7 @@ custom-new-theme-mode Do not call this mode function yourself. It is meant for internal use." (use-local-map custom-new-theme-mode-map) (custom--initialize-widget-variables) - (set (make-local-variable 'revert-buffer-function) 'custom-theme-revert)) + (set (make-local-variable 'revert-buffer-function) #'custom-theme-revert)) (put 'custom-new-theme-mode 'mode-class 'special) (defvar custom-theme-name nil) @@ -118,13 +118,13 @@ customize-create-theme :tag " Visit Theme " :help-echo "Insert the settings of a pre-defined theme." :action (lambda (_widget &optional _event) - (call-interactively 'custom-theme-visit-theme))) + (call-interactively #'custom-theme-visit-theme))) (widget-insert " ") (widget-create 'push-button :tag " Merge Theme " :help-echo "Merge in the settings of a pre-defined theme." :action (lambda (_widget &optional _event) - (call-interactively 'custom-theme-merge-theme))) + (call-interactively #'custom-theme-merge-theme))) (widget-insert " ") (widget-create 'push-button :tag " Revert " @@ -142,7 +142,7 @@ customize-create-theme (widget-create 'text :value (format-time-string "Created %Y-%m-%d."))) (widget-create 'push-button - :notify (function custom-theme-write) + :notify #'custom-theme-write " Save Theme ") (when (eq theme 'user) (setq custom-theme--migrate-settings t) @@ -188,7 +188,7 @@ customize-create-theme :mouse-face 'highlight :pressed-face 'highlight :action (lambda (_widget &optional _event) - (call-interactively 'custom-theme-add-face))) + (call-interactively #'custom-theme-add-face))) ;; If THEME is non-nil, insert all of that theme's variables. (widget-insert "\n\n Theme variables:\n ") @@ -207,7 +207,7 @@ customize-create-theme :mouse-face 'highlight :pressed-face 'highlight :action (lambda (_widget &optional _event) - (call-interactively 'custom-theme-add-variable))) + (call-interactively #'custom-theme-add-variable))) (widget-insert ?\n) (widget-setup) (goto-char (point-min)) @@ -254,7 +254,7 @@ custom-theme-add-var-1 :tag (custom-unlispify-tag-name symbol) :value symbol :shown-value (list val) - :notify 'ignore + :notify #'ignore :custom-level 0 :custom-state 'hidden :custom-style 'simple)) @@ -313,7 +313,7 @@ custom-theme-visit-theme (interactive (list (intern (completing-read "Find custom theme: " - (mapcar 'symbol-name + (mapcar #'symbol-name (custom-available-themes)))))) (unless (custom-theme-name-valid-p theme) (error "No valid theme named `%s'" theme)) @@ -328,7 +328,7 @@ custom-theme-merge-theme (interactive (list (intern (completing-read "Merge custom theme: " - (mapcar 'symbol-name + (mapcar #'symbol-name (custom-available-themes)))))) (unless (eq theme 'user) (unless (custom-theme-name-valid-p theme) @@ -343,8 +343,8 @@ custom-theme-merge-theme (memq name '(custom-enabled-themes custom-safe-themes))) (funcall (if option - 'custom-theme-add-variable - 'custom-theme-add-face) + #'custom-theme-add-variable + #'custom-theme-add-face) name value))))) theme) @@ -475,7 +475,7 @@ describe-theme (interactive (list (intern (completing-read "Describe custom theme: " - (mapcar 'symbol-name + (mapcar #'symbol-name (custom-available-themes)))))) (unless (custom-theme-name-valid-p theme) (error "Invalid theme name `%s'" theme)) @@ -616,11 +616,11 @@ customize-themes (widget-create 'push-button :tag " Save Theme Settings " :help-echo "Save the selected themes for future sessions." - :action 'custom-theme-save) + :action #'custom-theme-save) (widget-insert ?\n) (widget-create 'checkbox :value custom-theme-allow-multiple-selections - :action 'custom-theme-selections-toggle) + :action #'custom-theme-selections-toggle) (widget-insert (propertize " Select more than one theme at a time" 'face '(variable-pitch (:height 0.9)))) @@ -632,13 +632,13 @@ customize-themes :value (custom-theme-enabled-p theme) :theme-name theme :help-echo help-echo - :action 'custom-theme-checkbox-toggle)) + :action #'custom-theme-checkbox-toggle)) (push (cons theme widget) custom--listed-themes) (widget-create-child-and-convert widget 'push-button :button-face-get 'ignore :mouse-face-get 'ignore :value (format " %s" theme) - :action 'widget-parent-action + :action #'widget-parent-action :help-echo help-echo) (widget-insert " -- " (propertize (custom-theme-summary theme) -- 2.18.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #6: 0006-Minor-custom.el-simplifications.patch --] [-- Type: text/x-diff, Size: 7892 bytes --] From 3ace45ec8797dce64f5bcc33eaeb423c11b0aa71 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Thu, 31 May 2018 18:37:02 +0100 Subject: [PATCH 6/8] Minor custom.el simplifications * lisp/custom.el (custom-quote): Duplicate macroexp-quote. (custom-load-symbol, customize-mark-to-save, customize-mark-as-set) (custom-theme-name-valid-p, enable-theme, custom-enabled-themes) (disable-theme): Simplify logic. --- lisp/custom.el | 103 ++++++++++++++++++++++--------------------------- 1 file changed, 46 insertions(+), 57 deletions(-) diff --git a/lisp/custom.el b/lisp/custom.el index 1c667c8aa2..a08f7fda70 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -630,14 +630,12 @@ custom-load-symbol (let ((custom-load-recursion t)) ;; Load these files if not already done, ;; to make sure we know all the dependencies of SYMBOL. - (condition-case nil - (require 'cus-load) - (error nil)) - (condition-case nil - (require 'cus-start) - (error nil)) + (ignore-errors + (require 'cus-load)) + (ignore-errors + (require 'cus-start)) (dolist (load (get symbol 'custom-loads)) - (cond ((symbolp load) (condition-case nil (require load) (error nil))) + (cond ((symbolp load) (ignore-errors (require load))) ;; This is subsumed by the test below, but it's much faster. ((assoc load load-history)) ;; This was just (assoc (locate-library load) load-history) @@ -655,7 +653,7 @@ custom-load-symbol ;; We are still loading it when we call this, ;; and it is not in load-history yet. ((equal load "cus-edit")) - (t (condition-case nil (load load) (error nil)))))))) + (t (ignore-errors (load load)))))))) \f (defvar custom-local-buffer nil "Non-nil, in a Customization buffer, means customize a specific buffer. @@ -688,16 +686,12 @@ custom-set-minor-mode (defun custom-quote (sexp) "Quote SEXP if it is not self quoting." - (if (or (memq sexp '(t nil)) - (keywordp sexp) - (and (listp sexp) - (memq (car sexp) '(lambda))) - (stringp sexp) - (numberp sexp) - (vectorp sexp) -;;; (and (fboundp 'characterp) -;;; (characterp sexp)) - ) + ;; Can't use `macroexp-quote' because it is loaded after `custom.el' + ;; during bootstrap. See `loadup.el'. + (if (and (not (consp sexp)) + (or (keywordp sexp) + (not (symbolp sexp)) + (booleanp sexp))) sexp (list 'quote sexp))) @@ -718,12 +712,10 @@ customize-mark-to-save (standard (get symbol 'standard-value)) (comment (get symbol 'customized-variable-comment))) ;; Save default value if different from standard value. - (if (or (null standard) - (not (equal value (condition-case nil - (eval (car standard)) - (error nil))))) - (put symbol 'saved-value (list (custom-quote value))) - (put symbol 'saved-value nil)) + (put symbol 'saved-value + (unless (and standard + (equal value (ignore-errors (eval (car standard))))) + (list (custom-quote value)))) ;; Clear customized information (set, but not saved). (put symbol 'customized-value nil) ;; Save any comment that might have been set. @@ -747,9 +739,8 @@ customize-mark-as-set (old (or (get symbol 'saved-value) (get symbol 'standard-value)))) ;; Mark default value as set if different from old value. (if (not (and old - (equal value (condition-case nil - (eval (car old)) - (error nil))))) + (equal value (ignore-errors + (eval (car old)))))) (progn (put symbol 'customized-value (list (custom-quote value))) (custom-push-theme 'theme-value symbol 'user 'set (custom-quote value))) @@ -1296,11 +1287,9 @@ custom-theme-load-confirm (defun custom-theme-name-valid-p (name) "Return t if NAME is a valid name for a Custom theme, nil otherwise. NAME should be a symbol." - (and (symbolp name) - name - (not (or (zerop (length (symbol-name name))) - (eq name 'user) - (eq name 'changed))))) + (and (not (memq name '(nil user changed))) + (symbolp name) + (not (string= "" (symbol-name name))))) (defun custom-available-themes () "Return a list of Custom themes available for loading. @@ -1356,8 +1345,8 @@ enable-theme (completing-read "Enable custom theme: " obarray (lambda (sym) (get sym 'theme-settings)) t)))) - (if (not (custom-theme-p theme)) - (error "Undefined Custom theme %s" theme)) + (unless (custom-theme-p theme) + (error "Undefined Custom theme %s" theme)) (let ((settings (get theme 'theme-settings))) ;; Loop through theme settings, recalculating vars/faces. (dolist (s settings) @@ -1397,18 +1386,18 @@ custom-enabled-themes (let (failures) (setq themes (delq 'user (delete-dups themes))) ;; Disable all themes not in THEMES. - (if (boundp symbol) - (dolist (theme (symbol-value symbol)) - (if (not (memq theme themes)) - (disable-theme theme)))) + (dolist (theme (and (boundp symbol) + (symbol-value symbol))) + (unless (memq theme themes) + (disable-theme theme))) ;; Call `enable-theme' or `load-theme' on each of THEMES. (dolist (theme (reverse themes)) (condition-case nil (if (custom-theme-p theme) (enable-theme theme) (load-theme theme)) - (error (setq failures (cons theme failures) - themes (delq theme themes))))) + (error (push theme failures) + (setq themes (delq theme themes))))) (enable-theme 'user) (custom-set-default symbol themes) (when failures @@ -1441,23 +1430,23 @@ disable-theme ;; If the face spec specified by this theme is in the ;; saved-face property, reset that property. (when (equal (nth 3 s) (get symbol 'saved-face)) - (put symbol 'saved-face (and val (cadr (car val))))))))) - ;; Recompute faces on all frames. - (dolist (frame (frame-list)) - ;; We must reset the fg and bg color frame parameters, or - ;; `face-set-after-frame-default' will use the existing - ;; parameters, which could be from the disabled theme. - (set-frame-parameter frame 'background-color - (custom--frame-color-default - frame :background "background" "Background" - "unspecified-bg" "white")) - (set-frame-parameter frame 'foreground-color - (custom--frame-color-default - frame :foreground "foreground" "Foreground" - "unspecified-fg" "black")) - (face-set-after-frame-default frame)) - (setq custom-enabled-themes - (delq theme custom-enabled-themes))))) + (put symbol 'saved-face (cadar val)))))))) + ;; Recompute faces on all frames. + (dolist (frame (frame-list)) + ;; We must reset the fg and bg color frame parameters, or + ;; `face-set-after-frame-default' will use the existing + ;; parameters, which could be from the disabled theme. + (set-frame-parameter frame 'background-color + (custom--frame-color-default + frame :background "background" "Background" + "unspecified-bg" "white")) + (set-frame-parameter frame 'foreground-color + (custom--frame-color-default + frame :foreground "foreground" "Foreground" + "unspecified-fg" "black")) + (face-set-after-frame-default frame)) + (setq custom-enabled-themes + (delq theme custom-enabled-themes)))) ;; Only used if window-system not null. (declare-function x-get-resource "frame.c" -- 2.18.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #7: 0007-Minor-cus-theme.el-simplifications.patch --] [-- Type: text/x-diff, Size: 3932 bytes --] From b7a38177595b54b5312078df9f99eacf29572421 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Thu, 10 May 2018 03:08:10 +0100 Subject: [PATCH 7/8] Minor cus-theme.el simplifications * lisp/cus-theme.el (custom-new-theme-mode, customize-themes) (custom-theme-choose-mode): Use setq-local. (customize-create-theme): Ditto. Use delete-all-overlays. (describe-theme-1, custom-theme-summary): Simplify logic. --- lisp/cus-theme.el | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/lisp/cus-theme.el b/lisp/cus-theme.el index 53389956ad..995c55b2b2 100644 --- a/lisp/cus-theme.el +++ b/lisp/cus-theme.el @@ -47,7 +47,7 @@ custom-new-theme-mode Do not call this mode function yourself. It is meant for internal use." (use-local-map custom-new-theme-mode-map) (custom--initialize-widget-variables) - (set (make-local-variable 'revert-buffer-function) #'custom-theme-revert)) + (setq-local revert-buffer-function #'custom-theme-revert)) (put 'custom-new-theme-mode 'mode-class 'special) (defvar custom-theme-name nil) @@ -93,15 +93,14 @@ customize-create-theme (switch-to-buffer (get-buffer-create (or buffer "*Custom Theme*"))) (let ((inhibit-read-only t)) (erase-buffer) - (dolist (ov (overlays-in (point-min) (point-max))) - (delete-overlay ov))) + (delete-all-overlays)) (custom-new-theme-mode) (make-local-variable 'custom-theme-name) - (set (make-local-variable 'custom-theme--save-name) theme) - (set (make-local-variable 'custom-theme-faces) nil) - (set (make-local-variable 'custom-theme-variables) nil) - (set (make-local-variable 'custom-theme-description) "") - (set (make-local-variable 'custom-theme--migrate-settings) nil) + (setq-local custom-theme--save-name theme) + (setq-local custom-theme-faces nil) + (setq-local custom-theme-variables nil) + (setq-local custom-theme-description "") + (setq-local custom-theme--migrate-settings nil) (make-local-variable 'custom-theme-insert-face-marker) (make-local-variable 'custom-theme-insert-variable-marker) (make-local-variable 'custom-theme--listed-faces) @@ -513,8 +512,7 @@ describe-theme-1 (condition-case nil (read (current-buffer)) (end-of-file nil))))) - (and sexp (listp sexp) - (eq (car sexp) 'deftheme) + (and (eq (car-safe sexp) 'deftheme) (setq doc (nth 2 sexp))))))) (princ "\n\nDocumentation:\n") (princ (if (stringp doc) @@ -552,10 +550,10 @@ custom-theme-choose-mode Do not call this mode function yourself. It is meant for internal use." (use-local-map custom-theme-choose-mode-map) (custom--initialize-widget-variables) - (set (make-local-variable 'revert-buffer-function) - (lambda (_ignore-auto noconfirm) - (when (or noconfirm (y-or-n-p "Discard current choices? ")) - (customize-themes (current-buffer)))))) + (setq-local revert-buffer-function + (lambda (_ignore-auto noconfirm) + (when (or noconfirm (y-or-n-p "Discard current choices? ")) + (customize-themes (current-buffer)))))) (put 'custom-theme-choose-mode 'mode-class 'special) ;;;###autoload @@ -568,7 +566,7 @@ customize-themes (let ((inhibit-read-only t)) (erase-buffer)) (custom-theme-choose-mode) - (set (make-local-variable 'custom--listed-themes) nil) + (setq-local custom--listed-themes nil) (make-local-variable 'custom-theme-allow-multiple-selections) (and (null custom-theme-allow-multiple-selections) (> (length custom-enabled-themes) 1) @@ -662,8 +660,7 @@ custom-theme-summary (condition-case nil (read (current-buffer)) (end-of-file nil))))) - (and sexp (listp sexp) - (eq (car sexp) 'deftheme) + (and (eq (car-safe sexp) 'deftheme) (setq doc (nth 2 sexp)))))))) (cond ((null doc) "(no documentation available)") -- 2.18.0 [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #8: 0008-Tweak-subr-x.el-substring-functions.patch --] [-- Type: text/x-diff, Size: 4709 bytes --] From 93f87046bddff2023550b4a9977a46cea86050e6 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" <contovob@tcd.ie> Date: Fri, 1 Jun 2018 21:58:10 +0100 Subject: [PATCH 8/8] Tweak subr-x.el substring functions * lisp/emacs-lisp/subr-x.el (string-join): #'-quote function symbol. (string-trim-left, string-trim-right): Make better use of substring for minor speedup. * test/lisp/emacs-lisp/subr-x-tests.el (subr-x-test-string-trim-left, subr-x-test-string-trim-right) (subr-x-test-string-remove-prefix) (subr-x-test-string-remove-suffix): New tests. --- lisp/emacs-lisp/subr-x.el | 12 +++---- test/lisp/emacs-lisp/subr-x-tests.el | 47 ++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el index e03a81c892..20eb0d5d05 100644 --- a/lisp/emacs-lisp/subr-x.el +++ b/lisp/emacs-lisp/subr-x.el @@ -211,7 +211,7 @@ string-empty-p (defsubst string-join (strings &optional separator) "Join all STRINGS using SEPARATOR." - (mapconcat 'identity strings separator)) + (mapconcat #'identity strings separator)) (define-obsolete-function-alias 'string-reverse 'reverse "25.1") @@ -219,17 +219,17 @@ string-trim-left "Trim STRING of leading string matching REGEXP. REGEXP defaults to \"[ \\t\\n\\r]+\"." - (if (string-match (concat "\\`\\(?:" (or regexp "[ \t\n\r]+")"\\)") string) - (replace-match "" t t string) + (if (string-match (concat "\\`\\(?:" (or regexp "[ \t\n\r]+") "\\)") string) + (substring string (match-end 0)) string)) (defsubst string-trim-right (string &optional regexp) "Trim STRING of trailing string matching REGEXP. REGEXP defaults to \"[ \\t\\n\\r]+\"." - (if (string-match (concat "\\(?:" (or regexp "[ \t\n\r]+") "\\)\\'") string) - (replace-match "" t t string) - string)) + (let ((i (string-match-p (concat "\\(?:" (or regexp "[ \t\n\r]+") "\\)\\'") + string))) + (if i (substring string 0 i) string))) (defsubst string-trim (string &optional trim-left trim-right) "Trim STRING of leading and trailing strings matching TRIM-LEFT and TRIM-RIGHT. diff --git a/test/lisp/emacs-lisp/subr-x-tests.el b/test/lisp/emacs-lisp/subr-x-tests.el index f7f0ef384f..81467bab2d 100644 --- a/test/lisp/emacs-lisp/subr-x-tests.el +++ b/test/lisp/emacs-lisp/subr-x-tests.el @@ -532,6 +532,53 @@ (format "abs sum is: %s")) "abs sum is: 15"))) +\f +;; Substring tests + +(ert-deftest subr-x-test-string-trim-left () + "Test `string-trim-left' behavior." + (should (equal (string-trim-left "") "")) + (should (equal (string-trim-left " \t\n\r") "")) + (should (equal (string-trim-left " \t\n\ra") "a")) + (should (equal (string-trim-left "a \t\n\r") "a \t\n\r")) + (should (equal (string-trim-left "" "") "")) + (should (equal (string-trim-left "a" "") "a")) + (should (equal (string-trim-left "aa" "a*") "")) + (should (equal (string-trim-left "ba" "a*") "ba")) + (should (equal (string-trim-left "aa" "a*?") "aa")) + (should (equal (string-trim-left "aa" "a+?") "a"))) + +(ert-deftest subr-x-test-string-trim-right () + "Test `string-trim-right' behavior." + (should (equal (string-trim-right "") "")) + (should (equal (string-trim-right " \t\n\r") "")) + (should (equal (string-trim-right " \t\n\ra") " \t\n\ra")) + (should (equal (string-trim-right "a \t\n\r") "a")) + (should (equal (string-trim-right "" "") "")) + (should (equal (string-trim-right "a" "") "a")) + (should (equal (string-trim-right "aa" "a*") "")) + (should (equal (string-trim-right "ab" "a*") "ab")) + (should (equal (string-trim-right "aa" "a*?") ""))) + +(ert-deftest subr-x-test-string-remove-prefix () + "Test `string-remove-prefix' behavior." + (should (equal (string-remove-prefix "" "") "")) + (should (equal (string-remove-prefix "" "a") "a")) + (should (equal (string-remove-prefix "a" "") "")) + (should (equal (string-remove-prefix "a" "b") "b")) + (should (equal (string-remove-prefix "a" "a") "")) + (should (equal (string-remove-prefix "a" "aa") "a")) + (should (equal (string-remove-prefix "a" "ab") "b"))) + +(ert-deftest subr-x-test-string-remove-suffix () + "Test `string-remove-suffix' behavior." + (should (equal (string-remove-suffix "" "") "")) + (should (equal (string-remove-suffix "" "a") "a")) + (should (equal (string-remove-suffix "a" "") "")) + (should (equal (string-remove-suffix "a" "b") "b")) + (should (equal (string-remove-suffix "a" "a") "")) + (should (equal (string-remove-suffix "a" "aa") "a")) + (should (equal (string-remove-suffix "a" "ba") "b"))) (provide 'subr-x-tests) ;;; subr-x-tests.el ends here -- 2.18.0 [-- Attachment #9: Type: text/plain, Size: 539 bytes --] "Basil L. Contovounesios" <contovob@tcd.ie> writes: > Stefan Monnier <monnier@IRO.UMontreal.CA> writes: > >>> Fair enough, though it's looking like the simplest solution is to keep >>> the original (when (file-directory-p dir) ...) check and avoid cl-lib >>> altogether. >> >> Agreed, with a comment explaining that cl-lib macros can't be used at >> this point for bootstrap reasons. > > How's the attached (see [PATCH 3/8])? Too verbose? Anything holding this up on my end? I reattach the patches for convenience. Thanks, -- Basil ^ permalink raw reply related [flat|nested] 33+ messages in thread
* Re: Byte-compilation of custom themes 2018-07-03 7:57 ` Basil L. Contovounesios @ 2018-07-11 1:40 ` Stefan Monnier 2018-07-11 6:05 ` Basil L. Contovounesios 0 siblings, 1 reply; 33+ messages in thread From: Stefan Monnier @ 2018-07-11 1:40 UTC (permalink / raw To: emacs-devel > Anything holding this up on my end? > I reattach the patches for convenience. Looks good to me. Do you have access rights to push, or do you need someone else to do it? Stefan ^ permalink raw reply [flat|nested] 33+ messages in thread
* Re: Byte-compilation of custom themes 2018-07-11 1:40 ` Stefan Monnier @ 2018-07-11 6:05 ` Basil L. Contovounesios 0 siblings, 0 replies; 33+ messages in thread From: Basil L. Contovounesios @ 2018-07-11 6:05 UTC (permalink / raw To: Stefan Monnier; +Cc: emacs-devel Stefan Monnier <monnier@iro.umontreal.ca> writes: >> Anything holding this up on my end? >> I reattach the patches for convenience. > > Looks good to me. Do you have access rights to push, or do you need > someone else to do it? The latter, thanks. -- Basil ^ permalink raw reply [flat|nested] 33+ messages in thread
end of thread, other threads:[~2018-07-11 6:05 UTC | newest] Thread overview: 33+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2018-01-20 21:01 Byte-compilation of custom themes Basil L. Contovounesios 2018-01-24 16:16 ` Stefan Monnier 2018-01-30 22:16 ` Basil L. Contovounesios 2018-01-31 2:26 ` Stefan Monnier 2018-02-01 0:45 ` Basil L. Contovounesios 2018-02-02 14:25 ` Stefan Monnier 2018-05-10 2:49 ` Basil L. Contovounesios 2018-05-10 2:54 ` Basil L. Contovounesios 2018-05-11 14:07 ` Eli Zaretskii 2018-05-11 14:02 ` Eli Zaretskii 2018-05-11 15:16 ` Basil L. Contovounesios 2018-05-11 16:03 ` Stefan Monnier 2018-05-11 20:03 ` Basil L. Contovounesios 2018-05-11 17:32 ` Eli Zaretskii 2018-05-11 20:43 ` Basil L. Contovounesios 2018-05-12 7:04 ` Eli Zaretskii 2018-06-01 20:48 ` Basil L. Contovounesios 2018-06-01 21:07 ` Basil L. Contovounesios 2018-06-02 11:24 ` Eli Zaretskii 2018-06-02 18:53 ` Basil L. Contovounesios 2018-06-02 19:32 ` Eli Zaretskii 2018-06-02 20:02 ` Basil L. Contovounesios 2018-06-03 3:52 ` Stefan Monnier 2018-06-03 11:21 ` Basil L. Contovounesios 2018-06-03 15:11 ` Eli Zaretskii 2018-06-03 16:08 ` Basil L. Contovounesios 2018-06-03 16:16 ` Eli Zaretskii 2018-06-03 17:48 ` Basil L. Contovounesios 2018-06-03 20:22 ` Stefan Monnier 2018-06-04 1:33 ` Basil L. Contovounesios 2018-07-03 7:57 ` Basil L. Contovounesios 2018-07-11 1:40 ` Stefan Monnier 2018-07-11 6:05 ` Basil L. Contovounesios
Code repositories for project(s) associated with this external index https://git.savannah.gnu.org/cgit/emacs.git https://git.savannah.gnu.org/cgit/emacs/org-mode.git This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.