commit 9c8bef5134b054e7958c33b9bd332a125fc7121b (HEAD, refs/remotes/origin/master) Author: Lars Ingebrigtsen Date: Mon May 31 10:24:23 2021 +0200 Remove messaging in ediff-make-diff2-buffer * lisp/vc/ediff-diff.el (ediff-make-diff2-buffer): Remove message that's often misleading when diffing buffers (that may be unsaved) (bug#13091). diff --git a/lisp/vc/ediff-diff.el b/lisp/vc/ediff-diff.el index 270c99ef1f..0965e888f0 100644 --- a/lisp/vc/ediff-diff.el +++ b/lisp/vc/ediff-diff.el @@ -231,10 +231,7 @@ one optional arguments, diff-number to refine.") (sit-for 2) ;; 1 is an error exit code 1) - (t (message "Computing differences between %s and %s ..." - (file-name-nondirectory file1) - (file-name-nondirectory file2)) - ;; this erases the diff buffer automatically + (t ;; this erases the diff buffer automatically (ediff-exec-process ediff-diff-program diff-buffer 'synchronize commit d51e6af9a70fac29881edf4e303d4f1ef4ec2b4a Author: Lars Ingebrigtsen Date: Mon May 31 08:17:00 2021 +0200 Put ELP results in a special-mode buffer * lisp/emacs-lisp/elp.el (elp-results): Make `q' work in ELP results buffer (bug#14104). (elp-results-mode): Define as an empty special mode derivation. diff --git a/lisp/emacs-lisp/elp.el b/lisp/emacs-lisp/elp.el index 2ee19a35b2..7c7961c4d5 100644 --- a/lisp/emacs-lisp/elp.el +++ b/lisp/emacs-lisp/elp.el @@ -483,6 +483,10 @@ original definition, use \\[elp-restore-function] or \\[elp-restore-all]." 'face 'link 'help-echo "mouse-2 or RET jumps to definition"))) +(define-derived-mode elp-results-mode special-mode "ELP" + "Mode for ELP results" + :interactive nil) + ;;;###autoload (defun elp-results () "Display current profiling results. @@ -490,11 +494,12 @@ If `elp-reset-after-results' is non-nil, then current profiling information for all instrumented functions is reset after results are displayed." (interactive) - (let ((curbuf (current-buffer)) - (resultsbuf (if elp-recycle-buffers-p - (get-buffer-create elp-results-buffer) - (generate-new-buffer elp-results-buffer)))) - (set-buffer resultsbuf) + (pop-to-buffer + (if elp-recycle-buffers-p + (get-buffer-create elp-results-buffer) + (generate-new-buffer elp-results-buffer))) + (elp-results-mode) + (let ((inhibit-read-only t)) (erase-buffer) ;; get the length of the longest function name being profiled (let* ((longest 0) @@ -565,9 +570,6 @@ displayed." (if elp-sort-by-function (setq resvec (sort resvec elp-sort-by-function))) (mapc 'elp-output-result resvec)) - ;; now pop up results buffer - (set-buffer curbuf) - (pop-to-buffer resultsbuf) ;; copy results to standard-output? (if (or elp-use-standard-output noninteractive) (princ (buffer-substring (point-min) (point-max))) commit 2009832a8229ac90c255bdb0f2dd333e8a2a48be Author: Lars Ingebrigtsen Date: Mon May 31 07:29:51 2021 +0200 Make `menu-bar-select-buffer' obsolete * lisp/menu-bar.el (menu-bar-select-buffer): Make obsolete (bug#15651). * lisp/msb.el (msb--select-buffer): Move function here and rename. (msb--make-keymap-menu): Use it. diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el index b71c650207..739e751d8a 100644 --- a/lisp/menu-bar.el +++ b/lisp/menu-bar.el @@ -2241,6 +2241,7 @@ Buffers menu is regenerated." "String to display in buffer listings for buffers not visiting a file.") (defun menu-bar-select-buffer () + (declare (obsolete nil "28.1")) (interactive) (switch-to-buffer last-command-event)) diff --git a/lisp/msb.el b/lisp/msb.el index 1064f94090..1f05e9db58 100644 --- a/lisp/msb.el +++ b/lisp/msb.el @@ -1052,9 +1052,12 @@ variable `msb-menu-cond'." (msb--split-menus-2 list 0 nil) list)) +(defun msb--select-buffer () + (interactive) + (switch-to-buffer last-command-event)) + (defun msb--make-keymap-menu (raw-menu) - (let ((end 'menu-bar-select-buffer) - (mcount 0)) + (let ((mcount 0)) (mapcar (lambda (sub-menu) (cond @@ -1063,7 +1066,7 @@ variable `msb-menu-cond'." (t (let ((buffers (mapcar (lambda (item) (cons (buffer-name (cdr item)) - (cons (car item) end))) + (cons (car item) 'msb--select-buffer))) (cdr sub-menu)))) (nconc (list (cl-incf mcount) (car sub-menu) 'keymap (car sub-menu)) commit 0dc195b4fe6a187df0763998062ecfaed7e3b61c Author: Lars Ingebrigtsen Date: Mon May 31 07:25:25 2021 +0200 Revert "Move menu-bar-select-buffer to msb.el" This reverts commit 253e52478c355dc29052c0d21013b8d06b473880. This is to be fixed in a different way in the next patch. diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el index 945152c05d..b71c650207 100644 --- a/lisp/menu-bar.el +++ b/lisp/menu-bar.el @@ -2240,6 +2240,10 @@ Buffers menu is regenerated." (defvar-local list-buffers-directory nil "String to display in buffer listings for buffers not visiting a file.") +(defun menu-bar-select-buffer () + (interactive) + (switch-to-buffer last-command-event)) + (defun menu-bar-select-frame (frame) (make-frame-visible frame) (raise-frame frame) diff --git a/lisp/msb.el b/lisp/msb.el index 47221d24d4..1064f94090 100644 --- a/lisp/msb.el +++ b/lisp/msb.el @@ -1052,10 +1052,6 @@ variable `msb-menu-cond'." (msb--split-menus-2 list 0 nil) list)) -(defun menu-bar-select-buffer () - (interactive) - (switch-to-buffer last-command-event)) - (defun msb--make-keymap-menu (raw-menu) (let ((end 'menu-bar-select-buffer) (mcount 0)) commit 415ae812e93aa992c206bfb3d1c382d78209b8fe Author: Lars Ingebrigtsen Date: Mon May 31 07:22:12 2021 +0200 Use buffer-local-boundp in describe-variable * lisp/help-fns.el (describe-variable): Use `buffer-local-boundp'. diff --git a/lisp/help-fns.el b/lisp/help-fns.el index c8f078cb85..5a805a2302 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el @@ -1029,10 +1029,7 @@ it is displayed along with the global value." ;; Since the variable may only exist in the ;; original buffer, we have to look for it ;; there. - (condition-case nil - (buffer-local-value vv orig-buffer) - (:success t) - (void-variable nil))))) + (buffer-local-boundp vv orig-buffer)))) t nil nil (if (symbolp v) (symbol-name v)))) (list (if (equal val "") commit 77f67d12f68a9fba210337b9ad38f049ec601fcb Author: Lars Ingebrigtsen Date: Mon May 31 07:21:09 2021 +0200 Add new convenience function `buffer-local-boundp' * doc/lispref/variables.texi (Creating Buffer-Local): Document it. * lisp/subr.el (buffer-local-boundp): New function. * src/data.c (Flocal_variable_p): Mention it. diff --git a/doc/lispref/variables.texi b/doc/lispref/variables.texi index 36abc316cb..62c76f09c0 100644 --- a/doc/lispref/variables.texi +++ b/doc/lispref/variables.texi @@ -1582,6 +1582,12 @@ buffer-local binding in buffer @var{buffer}, it returns the default value (@pxref{Default Value}) of @var{variable} instead. @end defun +@defun buffer-local-boundp variable buffer +This returns non-@code{nil} if there's either a buffer-local binding +of @var{variable} (a symbol) in buffer @var{buffer}, or @var{variable} +has a global binding. +@end defun + @defun buffer-local-variables &optional buffer This function returns a list describing the buffer-local variables in buffer @var{buffer}. (If @var{buffer} is omitted, the current buffer diff --git a/etc/NEWS b/etc/NEWS index c6e7084118..6622861aaf 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2726,6 +2726,10 @@ customize them. * Lisp Changes in Emacs 28.1 ++++ +** New function 'buffer-local-boundp'. +This predicate says whether a symbol is bound in a specific buffer. + --- ** Emacs now attempts to test for high-rate subprocess output more fairly. When several subprocesses produce output simultaneously at high rate, diff --git a/lisp/subr.el b/lisp/subr.el index 88740159b9..e49c277335 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -195,6 +195,14 @@ buffer-local wherever it is set." (list 'progn (list 'defvar var val docstring) (list 'make-variable-buffer-local (list 'quote var)))) +(defun buffer-local-boundp (symbol buffer) + "Return non-nil if SYMBOL is bound in BUFFER. +Also see `local-variable-p'." + (condition-case nil + (buffer-local-value symbol buffer) + (:success t) + (void-variable nil))) + (defmacro push (newelt place) "Add NEWELT to the list stored in the generalized variable PLACE. This is morally equivalent to (setf PLACE (cons NEWELT PLACE)), diff --git a/src/data.c b/src/data.c index d547f5da5e..059f31e514 100644 --- a/src/data.c +++ b/src/data.c @@ -2200,7 +2200,9 @@ From now on the default value will apply in this buffer. Return VARIABLE. */) DEFUN ("local-variable-p", Flocal_variable_p, Slocal_variable_p, 1, 2, 0, doc: /* Non-nil if VARIABLE has a local binding in buffer BUFFER. -BUFFER defaults to the current buffer. */) +BUFFER defaults to the current buffer. + +Also see `buffer-local-boundp'.*/) (Lisp_Object variable, Lisp_Object buffer) { struct buffer *buf = decode_buffer (buffer); diff --git a/test/lisp/subr-tests.el b/test/lisp/subr-tests.el index 1e14673216..375251cffc 100644 --- a/test/lisp/subr-tests.el +++ b/test/lisp/subr-tests.el @@ -684,5 +684,15 @@ See https://debbugs.gnu.org/cgi/bugreport.cgi?bug=19350." (should (>= (length (apropos-internal "^help" #'commandp)) 15)) (should-not (apropos-internal "^next-line$" #'keymapp))) + +(ert-deftest test-buffer-local-boundp () + (let ((buf (generate-new-buffer "boundp"))) + (with-current-buffer buf + (setq-local test-boundp t)) + (setq test-global-boundp t) + (should (buffer-local-boundp 'test-boundp buf)) + (should-not (buffer-local-boundp 'test-not-boundp buf)) + (should (buffer-local-boundp 'test-global-boundp buf)))) + (provide 'subr-tests) ;;; subr-tests.el ends here commit db91108315016875ae912c0cbd6ccde563511b19 Author: Daniel Mendler Date: Mon May 31 06:49:37 2021 +0200 Speed up `describe-variable' completion predicate * lisp/help-fns.el (describe-variable): Do not switch to the original buffer in the predicate (bug#48738). diff --git a/lisp/help-fns.el b/lisp/help-fns.el index 666583db72..c8f078cb85 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el @@ -1024,12 +1024,15 @@ it is displayed along with the global value." (format-prompt "Describe variable" (and (symbolp v) v)) #'help--symbol-completion-table (lambda (vv) - ;; In case the variable only exists in the buffer - ;; the command we switch back to that buffer before - ;; we examine the variable. - (with-current-buffer orig-buffer - (or (get vv 'variable-documentation) - (and (boundp vv) (not (keywordp vv)))))) + (or (get vv 'variable-documentation) + (and (not (keywordp vv)) + ;; Since the variable may only exist in the + ;; original buffer, we have to look for it + ;; there. + (condition-case nil + (buffer-local-value vv orig-buffer) + (:success t) + (void-variable nil))))) t nil nil (if (symbolp v) (symbol-name v)))) (list (if (equal val "") commit 7733076638f5cb427db3b2151ce33f309c08abc3 Author: Lars Ingebrigtsen Date: Mon May 31 06:36:23 2021 +0200 Fix error in xdg-mime-apps-files when XDG_CURRENT_DESKTOP is defined * lisp/xdg.el (xdg-mime-apps-files): Don't bug out when XDG_CURRENT_DESKTOP is bound (bug#48748). diff --git a/lisp/xdg.el b/lisp/xdg.el index 11039499ea..0bdfd114c4 100644 --- a/lisp/xdg.el +++ b/lisp/xdg.el @@ -231,7 +231,7 @@ admin config, and finally system cached associations." (desktop (getenv "XDG_CURRENT_DESKTOP")) res) (when desktop - (setq desktop (format "%s-mimeapps.list" desktop))) + (setq desktop (list (format "%s-mimeapps.list" desktop)))) (dolist (name (cons "mimeapps.list" desktop)) (push (expand-file-name name (xdg-config-home)) res) (push (expand-file-name (format "applications/%s" name) (xdg-data-home)) commit ed72a8ccd5e32e7752102f223fac12e7ad72709b Author: Philipp Stephani Date: Sun May 30 22:39:54 2021 +0200 Document that the 'syntax-propertize-function' may move point. The functions generated by 'syntax-propertize-rules' don't use 'save-excursion', but 'syntax-propertize' does, so we might as well document that the 'syntax-propertize-function' may move point. * doc/lispref/syntax.texi (Syntax Properties): Document that the 'syntax-propertize-function' may move point. diff --git a/doc/lispref/syntax.texi b/doc/lispref/syntax.texi index 2df6c15c4c..bde7075b0d 100644 --- a/doc/lispref/syntax.texi +++ b/doc/lispref/syntax.texi @@ -572,12 +572,14 @@ The function is called by @code{syntax-ppss} (@pxref{Position Parse}), and by Font Lock mode during syntactic fontification (@pxref{Syntactic Font Lock}). It is called with two arguments, @var{start} and @var{end}, which are the starting and ending positions of the text on -which it should act. It is allowed to call @code{syntax-ppss} on any -position before @var{end}, but if a Lisp program calls -@code{syntax-ppss} on some position and later modifies the buffer at -some earlier position, then it is that program's responsibility to -call @code{syntax-ppss-flush-cache} to flush the now obsolete info -from the cache. +which it should act. It is allowed to arbitrarily move point within +the region delimited by @var{start} and @var{end}; such motions don't +need to use @code{save-excursion} (@pxref{Excursions}). It is also +allowed to call @code{syntax-ppss} on any position before @var{end}, +but if a Lisp program calls @code{syntax-ppss} on some position and +later modifies the buffer at some earlier position, then it is that +program's responsibility to call @code{syntax-ppss-flush-cache} to +flush the now obsolete info from the cache. @strong{Caution:} When this variable is non-@code{nil}, Emacs removes @code{syntax-table} text properties arbitrarily and relies on commit 3988411f6c6a1170bca0831874233ff4b739009c Author: Philipp Stephani Date: Sun May 30 22:38:48 2021 +0200 Give 'syntax-propertize-wholelines' a docstring. This function is generally useful. * lisp/emacs-lisp/syntax.el (syntax-propertize-wholelines): Add docstring. diff --git a/lisp/emacs-lisp/syntax.el b/lisp/emacs-lisp/syntax.el index 6d5b04b83b..0bb1b8916b 100644 --- a/lisp/emacs-lisp/syntax.el +++ b/lisp/emacs-lisp/syntax.el @@ -125,6 +125,10 @@ otherwise nil. That construct can be a two character comment delimiter or an Escaped or Char-quoted character.")) (defun syntax-propertize-wholelines (start end) + "Extend the region delimited by START and END to whole lines. +This function is useful for +`syntax-propertize-extend-region-functions'; +see Info node `(elisp) Syntax Properties'." (goto-char start) (cons (line-beginning-position) (progn (goto-char end) commit a5b57fc6af7ec87c59d00a7631576f9f4bf99841 Author: Stephen Gildea Date: Sun May 30 11:05:42 2021 -0700 time-stamp: fix minor bug when parsing option combos * lisp/time-stamp.el (time-stamp-string-preprocess): Handle digit options correctly to avoid overcounting colon options. * test/lisp/time-stamp-tests.el (time-stamp-format-time-zone-offset): Add a new test case that would have caught the option-parsing error. diff --git a/lisp/time-stamp.el b/lisp/time-stamp.el index 42455ddfe3..0cc566f0d8 100644 --- a/lisp/time-stamp.el +++ b/lisp/time-stamp.el @@ -499,7 +499,8 @@ and all `time-stamp-format' compatibility." (< ind fmt-len))) (if (and (<= ?0 cur-char) (>= ?9 cur-char)) ;; get format width - (let ((field-index ind)) + (let ((field-index ind) + (first-digit cur-char)) (while (progn (setq ind (1+ ind)) (setq cur-char (if (< ind fmt-len) @@ -510,6 +511,7 @@ and all `time-stamp-format' compatibility." (setq field-width (substring format field-index ind)) (setq ind (1- ind)) + (setq cur-char first-digit) t)))) (setq prev-char cur-char) ;; some characters we actually use diff --git a/test/lisp/time-stamp-tests.el b/test/lisp/time-stamp-tests.el index c021353630..b42271e4e5 100644 --- a/test/lisp/time-stamp-tests.el +++ b/test/lisp/time-stamp-tests.el @@ -525,7 +525,7 @@ (should (equal (time-stamp-string "%#Z" ref-time1) utc-abbr))))) (ert-deftest time-stamp-format-time-zone-offset () - "Test time-stamp format %z." + "Tests time-stamp legacy format %z and new offset format %5z." (with-time-stamp-test-env (let ((utc-abbr (format-time-string "%#Z" ref-time1 t))) ;; documented 1995-2019, warned since 2019, will change @@ -544,6 +544,7 @@ (should (equal (time-stamp-string "%_z" ref-time1) "+0000")) (should (equal (time-stamp-string "%:z" ref-time1) "+00:00")) (should (equal (time-stamp-string "%::z" ref-time1) "+00:00:00")) + (should (equal (time-stamp-string "%9::z" ref-time1) "+00:00:00")) (should (equal (time-stamp-string "%:::z" ref-time1) "+00")))) (ert-deftest time-stamp-format-non-date-conversions () commit d6dc66053d846b6fc041889b4d0f383c8dac4da3 Author: Stephen Gildea Date: Sun May 30 09:08:08 2021 -0700 time-stamp: refactor time-stamp-string-preprocess * lisp/time-stamp.el (time-stamp-string-preprocess): Reduce lifetime of some loop-local variables to be less error-prone. diff --git a/lisp/time-stamp.el b/lisp/time-stamp.el index b9eab95b23..42455ddfe3 100644 --- a/lisp/time-stamp.el +++ b/lisp/time-stamp.el @@ -462,195 +462,201 @@ and all `time-stamp-format' compatibility." (let ((fmt-len (length format)) (ind 0) cur-char - (prev-char nil) - (result "") - field-width - field-result - alt-form change-case upcase - (paren-level 0)) + (result "")) (while (< ind fmt-len) (setq cur-char (aref format ind)) (setq result - (concat result - (cond - ((eq cur-char ?%) - ;; eat any additional args to allow for future expansion - (setq alt-form 0 change-case nil upcase nil field-width "") - (while (progn - (setq ind (1+ ind)) - (setq cur-char (if (< ind fmt-len) - (aref format ind) - ?\0)) - (or (eq ?. cur-char) - (eq ?, cur-char) (eq ?: cur-char) (eq ?@ cur-char) - (eq ?- cur-char) (eq ?+ cur-char) (eq ?_ cur-char) - (eq ?\s cur-char) (eq ?# cur-char) (eq ?^ cur-char) - (and (eq ?\( cur-char) - (not (eq prev-char ?\\)) - (setq paren-level (1+ paren-level))) - (if (and (eq ?\) cur-char) + (concat + result + (cond + ((eq cur-char ?%) + (let ((prev-char nil) + (field-width "") + field-result + (alt-form 0) + (change-case nil) + (upcase nil) + (paren-level 0)) + ;; eat any additional args to allow for future expansion + (while (progn + (setq ind (1+ ind)) + (setq cur-char (if (< ind fmt-len) + (aref format ind) + ?\0)) + (or (eq ?. cur-char) + (eq ?, cur-char) (eq ?: cur-char) (eq ?@ cur-char) + (eq ?- cur-char) (eq ?+ cur-char) (eq ?_ cur-char) + (eq ?\s cur-char) (eq ?# cur-char) (eq ?^ cur-char) + (and (eq ?\( cur-char) (not (eq prev-char ?\\)) - (> paren-level 0)) - (setq paren-level (1- paren-level)) - (and (> paren-level 0) - (< ind fmt-len))) - (if (and (<= ?0 cur-char) (>= ?9 cur-char)) - ;; get format width - (let ((field-index ind)) - (while (progn - (setq ind (1+ ind)) - (setq cur-char (if (< ind fmt-len) - (aref format ind) - ?\0)) - (and (<= ?0 cur-char) (>= ?9 cur-char)))) - (setq field-width (substring format field-index ind)) - (setq ind (1- ind)) - t)))) - (setq prev-char cur-char) - ;; some characters we actually use - (cond ((eq cur-char ?:) - (setq alt-form (1+ alt-form))) - ((eq cur-char ?#) - (setq change-case t)) - ((eq cur-char ?^) - (setq upcase t)) - ((eq cur-char ?-) - (setq field-width "1")) - ((eq cur-char ?_) - (setq field-width "2")))) - (setq field-result - (cond - ((eq cur-char ?%) - "%") - ((eq cur-char ?a) ;day of week - (if (> alt-form 0) - (if (string-equal field-width "") - (time-stamp--format "%A" time) - "") ;discourage "%:3a" - (if (or change-case upcase) - (time-stamp--format "%#a" time) - (time-stamp--format "%a" time)))) - ((eq cur-char ?A) - (if (or change-case upcase (not (string-equal field-width ""))) - (time-stamp--format "%#A" time) - (time-stamp--format "%A" time))) - ((eq cur-char ?b) ;month name - (if (> alt-form 0) - (if (string-equal field-width "") - (time-stamp--format "%B" time) - "") ;discourage "%:3b" - (if (or change-case upcase) - (time-stamp--format "%#b" time) - (time-stamp--format "%b" time)))) - ((eq cur-char ?B) - (if (or change-case upcase (not (string-equal field-width ""))) - (time-stamp--format "%#B" time) - (time-stamp--format "%B" time))) - ((eq cur-char ?d) ;day of month, 1-31 - (time-stamp-do-number cur-char alt-form field-width time)) - ((eq cur-char ?H) ;hour, 0-23 - (time-stamp-do-number cur-char alt-form field-width time)) - ((eq cur-char ?I) ;hour, 1-12 - (time-stamp-do-number cur-char alt-form field-width time)) - ((eq cur-char ?m) ;month number, 1-12 - (time-stamp-do-number cur-char alt-form field-width time)) - ((eq cur-char ?M) ;minute, 0-59 - (time-stamp-do-number cur-char alt-form field-width time)) - ((eq cur-char ?p) ;am or pm - (if change-case - (time-stamp--format "%#p" time) - (time-stamp--format "%p" time))) - ((eq cur-char ?P) ;AM or PM - (time-stamp--format "%p" time)) - ((eq cur-char ?S) ;seconds, 00-60 - (time-stamp-do-number cur-char alt-form field-width time)) - ((eq cur-char ?w) ;weekday number, Sunday is 0 - (time-stamp--format "%w" time)) - ((eq cur-char ?y) ;year - (if (> alt-form 0) - (string-to-number (time-stamp--format "%Y" time)) - (if (or (string-equal field-width "") - (<= (string-to-number field-width) 2)) - (string-to-number (time-stamp--format "%y" time)) - (time-stamp-conv-warn (format "%%%sy" field-width) "%Y") - (string-to-number (time-stamp--format "%Y" time))))) - ((eq cur-char ?Y) ;4-digit year - (string-to-number (time-stamp--format "%Y" time))) - ((eq cur-char ?z) ;time zone offset - (if change-case - "" ;discourage %z variations - (cond ((= alt-form 0) - (if (string-equal field-width "") - (progn - (time-stamp-conv-warn "%z" "%#Z") - (time-stamp--format "%#Z" time)) - (cond ((string-equal field-width "1") - (setq field-width "3")) ;%-z -> "+00" - ((string-equal field-width "2") - (setq field-width "5")) ;%_z -> "+0000" - ((string-equal field-width "4") - (setq field-width "0"))) ;discourage %4z - (time-stamp--format "%z" time))) - ((= alt-form 1) - (time-stamp--format "%:z" time)) - ((= alt-form 2) - (time-stamp--format "%::z" time)) - ((= alt-form 3) - (time-stamp--format "%:::z" time))))) - ((eq cur-char ?Z) ;time zone name - (if change-case - (time-stamp--format "%#Z" time) - (time-stamp--format "%Z" time))) - ((eq cur-char ?f) ;buffer-file-name, base name only - (if buffer-file-name - (file-name-nondirectory buffer-file-name) - time-stamp-no-file)) - ((eq cur-char ?F) ;buffer-file-name, full path - (or buffer-file-name - time-stamp-no-file)) - ((eq cur-char ?s) ;system name, legacy - (system-name)) - ((eq cur-char ?u) ;user name, legacy - (user-login-name)) - ((eq cur-char ?U) ;user full name, legacy - (user-full-name)) - ((eq cur-char ?l) ;login name - (user-login-name)) - ((eq cur-char ?L) ;full name of logged-in user - (user-full-name)) - ((eq cur-char ?h) ;mail host name - (or mail-host-address (system-name))) - ((eq cur-char ?q) ;unqualified host name - (let ((qualname (system-name))) - (if (string-match "\\." qualname) - (substring qualname 0 (match-beginning 0)) - qualname))) - ((eq cur-char ?Q) ;fully-qualified host name - (system-name)) - )) - (and (numberp field-result) - (= alt-form 0) - (string-equal field-width "") - ;; no width provided; set width for default - (setq field-width "02")) - (let ((padded-result - (format (format "%%%s%c" - field-width - (if (numberp field-result) ?d ?s)) - (or field-result "")))) - (let* ((initial-length (length padded-result)) - (desired-length (if (string-equal field-width "") - initial-length - (string-to-number field-width)))) - (if (> initial-length desired-length) - ;; truncate strings on right - (if (stringp field-result) - (substring padded-result 0 desired-length) - padded-result) ;numbers don't truncate - padded-result)))) - (t - (char-to-string cur-char))))) + (setq paren-level (1+ paren-level))) + (if (and (eq ?\) cur-char) + (not (eq prev-char ?\\)) + (> paren-level 0)) + (setq paren-level (1- paren-level)) + (and (> paren-level 0) + (< ind fmt-len))) + (if (and (<= ?0 cur-char) (>= ?9 cur-char)) + ;; get format width + (let ((field-index ind)) + (while (progn + (setq ind (1+ ind)) + (setq cur-char (if (< ind fmt-len) + (aref format ind) + ?\0)) + (and (<= ?0 cur-char) + (>= ?9 cur-char)))) + (setq field-width + (substring format field-index ind)) + (setq ind (1- ind)) + t)))) + (setq prev-char cur-char) + ;; some characters we actually use + (cond ((eq cur-char ?:) + (setq alt-form (1+ alt-form))) + ((eq cur-char ?#) + (setq change-case t)) + ((eq cur-char ?^) + (setq upcase t)) + ((eq cur-char ?-) + (setq field-width "1")) + ((eq cur-char ?_) + (setq field-width "2")))) + (setq field-result + (cond + ((eq cur-char ?%) + "%") + ((eq cur-char ?a) ;day of week + (if (> alt-form 0) + (if (string-equal field-width "") + (time-stamp--format "%A" time) + "") ;discourage "%:3a" + (if (or change-case upcase) + (time-stamp--format "%#a" time) + (time-stamp--format "%a" time)))) + ((eq cur-char ?A) + (if (or change-case upcase (not (string-equal field-width + ""))) + (time-stamp--format "%#A" time) + (time-stamp--format "%A" time))) + ((eq cur-char ?b) ;month name + (if (> alt-form 0) + (if (string-equal field-width "") + (time-stamp--format "%B" time) + "") ;discourage "%:3b" + (if (or change-case upcase) + (time-stamp--format "%#b" time) + (time-stamp--format "%b" time)))) + ((eq cur-char ?B) + (if (or change-case upcase (not (string-equal field-width + ""))) + (time-stamp--format "%#B" time) + (time-stamp--format "%B" time))) + ((eq cur-char ?d) ;day of month, 1-31 + (time-stamp-do-number cur-char alt-form field-width time)) + ((eq cur-char ?H) ;hour, 0-23 + (time-stamp-do-number cur-char alt-form field-width time)) + ((eq cur-char ?I) ;hour, 1-12 + (time-stamp-do-number cur-char alt-form field-width time)) + ((eq cur-char ?m) ;month number, 1-12 + (time-stamp-do-number cur-char alt-form field-width time)) + ((eq cur-char ?M) ;minute, 0-59 + (time-stamp-do-number cur-char alt-form field-width time)) + ((eq cur-char ?p) ;am or pm + (if change-case + (time-stamp--format "%#p" time) + (time-stamp--format "%p" time))) + ((eq cur-char ?P) ;AM or PM + (time-stamp--format "%p" time)) + ((eq cur-char ?S) ;seconds, 00-60 + (time-stamp-do-number cur-char alt-form field-width time)) + ((eq cur-char ?w) ;weekday number, Sunday is 0 + (time-stamp--format "%w" time)) + ((eq cur-char ?y) ;year + (if (> alt-form 0) + (string-to-number (time-stamp--format "%Y" time)) + (if (or (string-equal field-width "") + (<= (string-to-number field-width) 2)) + (string-to-number (time-stamp--format "%y" time)) + (time-stamp-conv-warn (format "%%%sy" field-width) "%Y") + (string-to-number (time-stamp--format "%Y" time))))) + ((eq cur-char ?Y) ;4-digit year + (string-to-number (time-stamp--format "%Y" time))) + ((eq cur-char ?z) ;time zone offset + (if change-case + "" ;discourage %z variations + (cond ((= alt-form 0) + (if (string-equal field-width "") + (progn + (time-stamp-conv-warn "%z" "%#Z") + (time-stamp--format "%#Z" time)) + (cond ((string-equal field-width "1") + (setq field-width "3")) ;%-z -> "+00" + ((string-equal field-width "2") + (setq field-width "5")) ;%_z -> "+0000" + ((string-equal field-width "4") + (setq field-width "0"))) ;discourage %4z + (time-stamp--format "%z" time))) + ((= alt-form 1) + (time-stamp--format "%:z" time)) + ((= alt-form 2) + (time-stamp--format "%::z" time)) + ((= alt-form 3) + (time-stamp--format "%:::z" time))))) + ((eq cur-char ?Z) ;time zone name + (if change-case + (time-stamp--format "%#Z" time) + (time-stamp--format "%Z" time))) + ((eq cur-char ?f) ;buffer-file-name, base name only + (if buffer-file-name + (file-name-nondirectory buffer-file-name) + time-stamp-no-file)) + ((eq cur-char ?F) ;buffer-file-name, full path + (or buffer-file-name + time-stamp-no-file)) + ((eq cur-char ?s) ;system name, legacy + (system-name)) + ((eq cur-char ?u) ;user name, legacy + (user-login-name)) + ((eq cur-char ?U) ;user full name, legacy + (user-full-name)) + ((eq cur-char ?l) ;login name + (user-login-name)) + ((eq cur-char ?L) ;full name of logged-in user + (user-full-name)) + ((eq cur-char ?h) ;mail host name + (or mail-host-address (system-name))) + ((eq cur-char ?q) ;unqualified host name + (let ((qualname (system-name))) + (if (string-match "\\." qualname) + (substring qualname 0 (match-beginning 0)) + qualname))) + ((eq cur-char ?Q) ;fully-qualified host name + (system-name)) + )) + (and (numberp field-result) + (= alt-form 0) + (string-equal field-width "") + ;; no width provided; set width for default + (setq field-width "02")) + (let ((padded-result + (format (format "%%%s%c" + field-width + (if (numberp field-result) ?d ?s)) + (or field-result "")))) + (let* ((initial-length (length padded-result)) + (desired-length (if (string-equal field-width "") + initial-length + (string-to-number field-width)))) + (if (> initial-length desired-length) + ;; truncate strings on right + (if (stringp field-result) + (substring padded-result 0 desired-length) + padded-result) ;numbers don't truncate + padded-result))))) + (t + (char-to-string cur-char))))) (setq ind (1+ ind))) result)) commit 15f46b9669fe93c62b5749e3326d4124188f54cd Author: Mauro Aranda Date: Sun May 30 09:35:13 2021 -0300 Do not reset settings when disabling a theme * lisp/custom.el (disable-theme): Don't call custom-push-theme, since that resets the theme settings and it isn't useful: we only need to remove the theme setting from the themed variable or face. This fixes a regression when "toggling" themes, introduced while fixing Bug#34027. (Bug#48736) diff --git a/lisp/custom.el b/lisp/custom.el index 078e3a8cf8..1db3f4fd39 100644 --- a/lisp/custom.el +++ b/lisp/custom.el @@ -1528,7 +1528,7 @@ See `custom-enabled-themes' for a list of enabled themes." (let* ((prop (car s)) (symbol (cadr s)) (val (assq-delete-all theme (get symbol prop)))) - (custom-push-theme prop symbol theme 'reset) + (put symbol prop val) (cond ((eq prop 'theme-value) (custom-theme-recalc-variable symbol) commit 23ad0f0c5adbeda9a0bd346138e2950cb5e5a136 Author: Eli Zaretskii Date: Sun May 30 11:16:59 2021 +0300 Don't account for character compositions in 'format' and friends 'lisp_string_width' is called from 'format' and 'format-message', which can be called both very early into Emacs initialization and in other contexts where using the font backend is impossible or undesirable. So this commit changes 'lisp_string_width' to try accounting for automatic compositions only when explicitly requested, and only 'string-width' does that; 'format' and 'format-message' don't. * src/character.c (lisp_string_width): Accept an additional argument AUTO_COMP; attempt accounting for auto-compositions only if that argument is non-zero. (Bug#48732) * src/editfns.c (styled_format): * src/character.c (Fstring_width): Callers of 'lisp_string_width' adjusted. diff --git a/src/character.c b/src/character.c index e874cf5e53..70e68961a5 100644 --- a/src/character.c +++ b/src/character.c @@ -328,12 +328,14 @@ strwidth (const char *str, ptrdiff_t len) compositions. If PRECISION > 0, return the width of longest substring that doesn't exceed PRECISION, and set number of characters and bytes of the substring in *NCHARS and *NBYTES - respectively. FROM and TO are zero-based character indices - that define the substring of STRING to consider. */ + respectively. FROM and TO are zero-based character indices that + define the substring of STRING to consider. If AUTO_COMP is + non-zero, account for automatic compositions in STRING. */ ptrdiff_t lisp_string_width (Lisp_Object string, ptrdiff_t from, ptrdiff_t to, - ptrdiff_t precision, ptrdiff_t *nchars, ptrdiff_t *nbytes) + ptrdiff_t precision, ptrdiff_t *nchars, ptrdiff_t *nbytes, + bool auto_comp) { /* This set multibyte to 0 even if STRING is multibyte when it contains only ascii and eight-bit-graphic, but that's @@ -370,7 +372,8 @@ lisp_string_width (Lisp_Object string, ptrdiff_t from, ptrdiff_t to, bytes = string_char_to_byte (string, end) - i_byte; } #ifdef HAVE_WINDOW_SYSTEM - else if (f && FRAME_WINDOW_P (f) + else if (auto_comp + && f && FRAME_WINDOW_P (f) && multibyte && find_automatic_composition (i, -1, &ignore, &end, &val, string) && end > i) @@ -471,7 +474,7 @@ usage: (string-width STRING &optional FROM TO) */) CHECK_STRING (str); validate_subarray (str, from, to, SCHARS (str), &ifrom, &ito); - XSETFASTINT (val, lisp_string_width (str, ifrom, ito, -1, NULL, NULL)); + XSETFASTINT (val, lisp_string_width (str, ifrom, ito, -1, NULL, NULL, true)); return val; } diff --git a/src/character.h b/src/character.h index 75351cd1ed..1a745484da 100644 --- a/src/character.h +++ b/src/character.h @@ -573,7 +573,7 @@ extern ptrdiff_t strwidth (const char *, ptrdiff_t); extern ptrdiff_t c_string_width (const unsigned char *, ptrdiff_t, int, ptrdiff_t *, ptrdiff_t *); extern ptrdiff_t lisp_string_width (Lisp_Object, ptrdiff_t, ptrdiff_t, - ptrdiff_t, ptrdiff_t *, ptrdiff_t *); + ptrdiff_t, ptrdiff_t *, ptrdiff_t *, bool); extern Lisp_Object Vchar_unify_table; extern Lisp_Object string_escape_byte8 (Lisp_Object); diff --git a/src/editfns.c b/src/editfns.c index 182d3ba6f2..aa0f46fea0 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -3390,7 +3390,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) ptrdiff_t nch, nby; nchars_string = SCHARS (arg); width = lisp_string_width (arg, 0, nchars_string, prec, - &nch, &nby); + &nch, &nby, false); if (prec < 0) nbytes = SBYTES (arg); else commit 7671d470781a3e68b4e39b43281c0b1b73c5eaa9 Author: Lars Ingebrigtsen Date: Sun May 30 08:25:18 2021 +0200 Clarify that `symbol-file' only works for symbols in Lisp files * lisp/subr.el (symbol-file): Mention help-C-file-name in the doc string (bug#14932). diff --git a/lisp/subr.el b/lisp/subr.el index 78507a552c..88740159b9 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -2476,7 +2476,11 @@ file name without extension. If TYPE is nil, then any kind of definition is acceptable. If TYPE is `defun', `defvar', or `defface', that specifies function definition, variable definition, or face definition only. -Otherwise TYPE is assumed to be a symbol property." +Otherwise TYPE is assumed to be a symbol property. + +This function only works for symbols defined in Lisp files. For +symbols that are defined in C files, use `help-C-file-name' +instead." (if (and (or (null type) (eq type 'defun)) (symbolp symbol) (autoloadp (symbol-function symbol))) commit c8ec798d70cc666cbd5d7e262e36ad2501aae4f7 Author: Lars Ingebrigtsen Date: Sun May 30 08:25:06 2021 +0200 Allow help-C-file-name to work on symbols designating subrs * lisp/help-fns.el (help-C-file-name): Allow working on symbols designating subrs (bug#14932). diff --git a/lisp/help-fns.el b/lisp/help-fns.el index 0b0ae4364c..666583db72 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el @@ -268,7 +268,9 @@ If we can't find the file name, nil is returned." (let ((docbuf (get-buffer-create " *DOC*")) (name (if (eq 'var kind) (concat "V" (symbol-name subr-or-var)) - (concat "F" (subr-name (advice--cd*r subr-or-var)))))) + (concat "F" (if (symbolp subr-or-var) + (symbol-name subr-or-var) + (subr-name (advice--cd*r subr-or-var))))))) (with-current-buffer docbuf (goto-char (point-min)) (if (eobp) commit db1de74e734086063fabb14b6e07789f63e60ad0 Author: Lars Ingebrigtsen Date: Sun May 30 08:10:15 2021 +0200 Fix kmacro-view-ring-2nd doc string * lisp/kmacro.el (kmacro-view-ring-2nd): Fix doc string (bug#15020). diff --git a/lisp/kmacro.el b/lisp/kmacro.el index afc486f4ed..8821e35c2d 100644 --- a/lisp/kmacro.el +++ b/lisp/kmacro.el @@ -482,7 +482,7 @@ without repeating the prefix." (defun kmacro-view-ring-2nd () - "Display the current head of the keyboard macro ring." + "Display the second macro in the keyboard macro ring." (interactive) (unless (kmacro-ring-empty-p) (kmacro-display (car (car kmacro-ring)) nil "2nd macro"))) commit 253e52478c355dc29052c0d21013b8d06b473880 Author: Lars Ingebrigtsen Date: Sun May 30 07:49:17 2021 +0200 Move menu-bar-select-buffer to msb.el * lisp/menu-bar.el (menu-bar-select-buffer): Move from here... (bug#15651). * lisp/msb.el (menu-bar-select-buffer): ... to here (which is the only usage in-tree in Emacs). diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el index b71c650207..945152c05d 100644 --- a/lisp/menu-bar.el +++ b/lisp/menu-bar.el @@ -2240,10 +2240,6 @@ Buffers menu is regenerated." (defvar-local list-buffers-directory nil "String to display in buffer listings for buffers not visiting a file.") -(defun menu-bar-select-buffer () - (interactive) - (switch-to-buffer last-command-event)) - (defun menu-bar-select-frame (frame) (make-frame-visible frame) (raise-frame frame) diff --git a/lisp/msb.el b/lisp/msb.el index 1064f94090..47221d24d4 100644 --- a/lisp/msb.el +++ b/lisp/msb.el @@ -1052,6 +1052,10 @@ variable `msb-menu-cond'." (msb--split-menus-2 list 0 nil) list)) +(defun menu-bar-select-buffer () + (interactive) + (switch-to-buffer last-command-event)) + (defun msb--make-keymap-menu (raw-menu) (let ((end 'menu-bar-select-buffer) (mcount 0)) commit 9e705206aca6f21f5b507af174cb12655dfa6b6b Author: Stephen Gildea Date: Sat May 29 22:54:30 2021 -0700 time-stamp: improve unit-test coverage * test/lisp/time-stamp-tests.el (time-stamp-format-year-4digit, time-stamp-format-ignored-modifiers): Improve coverage with more cases. (time-stamp-format-multiple-conversions): New test. diff --git a/test/lisp/time-stamp-tests.el b/test/lisp/time-stamp-tests.el index 4ae3c1917d..c021353630 100644 --- a/test/lisp/time-stamp-tests.el +++ b/test/lisp/time-stamp-tests.el @@ -486,7 +486,10 @@ "Test time-stamp format %Y." (with-time-stamp-test-env ;; implemented since 1997, documented since 2019 - (should (equal (time-stamp-string "%Y" ref-time1) "2006")))) + (should (equal (time-stamp-string "%Y" ref-time1) "2006")) + ;; numbers do not truncate + (should (equal (time-stamp-string "%2Y" ref-time1) "2006")) + (should (equal (time-stamp-string "%02Y" ref-time1) "2006")))) (ert-deftest time-stamp-format-am-pm () "Test time-stamp formats for AM and PM strings." @@ -586,6 +589,9 @@ (should (equal (time-stamp-string "%(st(u)ff)B" ref-time3) May)) ;; escaped parens do not change the nesting level (should (equal (time-stamp-string "%(st\\)u\\(ff)B" ref-time3) May)) + ;; incorrectly nested parens do not crash us + (should-not (equal (time-stamp-string "%(stuffB" ref-time3) May)) + (should-not (equal (time-stamp-string "%)B" ref-time3) May)) ;; not all punctuation is allowed (should-not (equal (time-stamp-string "%&B" ref-time3) May))))) @@ -594,6 +600,33 @@ (with-time-stamp-test-env (should (equal (time-stamp-string "No percent" ref-time1) "No percent")))) +(ert-deftest time-stamp-format-multiple-conversions () + "Tests that multiple %-conversions are independent." + (with-time-stamp-test-env + (let ((Mon (format-time-string "%a" ref-time1 t)) + (MON (format-time-string "%^a" ref-time1 t)) + (Monday (format-time-string "%A" ref-time1 t))) + ;; change-case flag is independent + (should (equal (time-stamp-string "%a.%#a.%a" ref-time1) + (concat Mon "." MON "." Mon))) + ;; up-case flag is independent + (should (equal (time-stamp-string "%a.%^a.%a" ref-time1) + (concat Mon "." MON "." Mon))) + ;; underscore flag is independent + (should (equal (time-stamp-string "%_d.%d.%_d" ref-time1) " 2.02. 2")) + ;; minus flag is independendent + (should (equal (time-stamp-string "%d.%-d.%d" ref-time1) "02.2.02")) + ;; 0 flag is independendent + (should (equal (time-stamp-string "%2d.%02d.%2d" ref-time1) " 2.02. 2")) + ;; field width is independent + (should (equal + (time-stamp-string "%6Y.%Y.%6Y" ref-time1) " 2006.2006. 2006")) + ;; colon modifier is independent + (should (equal (time-stamp-string "%a.%:a.%a" ref-time1) + (concat Mon "." Monday "." Mon))) + ;; format letter is independent + (should (equal (time-stamp-string "%H:%M" ref-time1) "15:04"))))) + (ert-deftest time-stamp-format-string-width () "Test time-stamp string width modifiers." (with-time-stamp-test-env commit fdfb3df92aae69026e6fe8f0b082c40fa903edc9 Author: Lars Ingebrigtsen Date: Sun May 30 07:06:48 2021 +0200 `minibuffer-exit-hook' doc string clarification * src/minibuf.c (syms_of_minibuf): `minibuffer-exit-hook' is run in the minubuffer usually, so don't claim that it's run after (bug#16524). diff --git a/src/minibuf.c b/src/minibuf.c index cffb7fe787..00069eabbe 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -2385,7 +2385,7 @@ default top level value is used. */); Vminibuffer_setup_hook = Qnil; DEFVAR_LISP ("minibuffer-exit-hook", Vminibuffer_exit_hook, - doc: /* Normal hook run just after exit from minibuffer. */); + doc: /* Normal hook run whenever a minibuffer is exited. */); Vminibuffer_exit_hook = Qnil; DEFVAR_LISP ("history-length", Vhistory_length, commit e247b4b69129d50e5c03814f42547059f16d4bbb Author: Daniel Martín Date: Sun May 30 06:41:52 2021 +0200 Add a new documentation group for overlays * lisp/emacs-lisp/shortdoc.el (overlay): Add documentation group for buffer overlays(bug#48730). diff --git a/lisp/emacs-lisp/shortdoc.el b/lisp/emacs-lisp/shortdoc.el index c9484dcb68..16e8307476 100644 --- a/lisp/emacs-lisp/shortdoc.el +++ b/lisp/emacs-lisp/shortdoc.el @@ -889,6 +889,52 @@ There can be any number of :example/:result elements." (unlock-buffer :no-value (lock-buffer))) +(define-short-documentation-group overlay + "Predicates" + (overlayp + :no-eval (overlayp some-overlay) + :eg-result t) + "Creation and Deletion" + (make-overlay + :args (beg end &optional buffer) + :no-eval (make-overlay 1 10) + :eg-result-string "#") + (delete-overlay + :no-eval (delete-overlay foo) + :eg-result t) + "Searching Overlays" + (overlays-at + :no-eval (overlays-at 15) + :eg-result-string "(#)") + (overlays-in + :no-eval (overlays-in 1 30) + :eg-result-string "(#)") + (next-overlay-change + :no-eval (next-overlay-change 1) + :eg-result 20) + (previous-overlay-change + :no-eval (previous-overlay-change 30) + :eg-result 20) + "Overlay Properties" + (overlay-start + :no-eval (overlay-start foo) + :eg-result 1) + (overlay-end + :no-eval (overlay-end foo) + :eg-result 10) + (overlay-put + :no-eval (overlay-put foo 'happy t) + :eg-result t) + (overlay-get + :no-eval (overlay-get foo 'happy) + :eg-result t) + (overlay-buffer + :no-eval (overlay-buffer foo)) + "Moving Overlays" + (move-overlay + :no-eval (move-overlay foo 5 20) + :eg-result-string "#")) + (define-short-documentation-group process (make-process :no-eval (make-process :name "foo" :command '("cat" "/tmp/foo")) commit 1230651ffdf7c271db4bb2901ea23298fcd9ecf3 Author: Daniel Martín Date: Sun May 30 06:41:24 2021 +0200 Improve the documentation of documentation groups * doc/lispref/help.texi (Documentation Groups): Fix typos and add an example. * lisp/emacs-lisp/shortdoc.el (define-short-documentation-group): Add :no-eval* and :result-string keywords to the docstring. (Bug#48730) diff --git a/doc/lispref/help.texi b/doc/lispref/help.texi index 298bec5230..dbbc34fb3a 100644 --- a/doc/lispref/help.texi +++ b/doc/lispref/help.texi @@ -839,7 +839,7 @@ evaluated, and the result used. For instance: @end example @noindent -will be printed as +will result in: @example (concat "foo" "bar" "zot") @@ -866,13 +866,14 @@ should be included. @end example @item :no-eval* -Like @code{:no-eval}, but alaways inserts @samp{[it depends]} as the -result. +Like @code{:no-eval}, but always inserts @samp{[it depends]} as the +result. For instance: @example :no-eval* (buffer-string) @end example +@noindent will result in: @example @@ -894,12 +895,21 @@ Used to output the result from non-evaluating example forms. @item :eg-result Used to output an example result from non-evaluating example forms. +For instance: @example :no-eval (looking-at "f[0-9]") :eg-result t @end example +@noindent +will result in: + +@example +(looking-at "f[0-9]") +eg. @click{} t +@end example + @item :result-string @itemx :eg-result-string These two are the same as @code{:result} and @code{:eg-result}, @@ -951,7 +961,7 @@ sections. @defun shortdoc-add-function shortdoc-add-function group section elem Lisp packages can add functions to groups with this command. Each -@var{elem} should be a function descriptions, as described above. +@var{elem} should be a function description, as described above. @var{group} is the function group, and @var{section} is what section in the function group to insert the function into. diff --git a/lisp/emacs-lisp/shortdoc.el b/lisp/emacs-lisp/shortdoc.el index 38d8ad6cc1..c9484dcb68 100644 --- a/lisp/emacs-lisp/shortdoc.el +++ b/lisp/emacs-lisp/shortdoc.el @@ -60,8 +60,10 @@ FUNCTIONS is a list of elements on the form: :args ARGS :eval EXAMPLE-FORM :no-eval EXAMPLE-FORM + :no-eval* EXAMPLE-FORM :no-value EXAMPLE-FORM :result RESULT-FORM + :result-string RESULT-FORM :eg-result RESULT-FORM :eg-result-string RESULT-FORM) commit b0d01982e2d5732390806ec5bbec6ebc01172601 Author: Lars Ingebrigtsen Date: Sun May 30 06:25:47 2021 +0200 Tweak octave continuation indentation * lisp/progmodes/octave.el (octave-smie-rules): Further tweak continuation indentation (bug#17955). diff --git a/lisp/progmodes/octave.el b/lisp/progmodes/octave.el index 5d877fc6ba..aff3066c69 100644 --- a/lisp/progmodes/octave.el +++ b/lisp/progmodes/octave.el @@ -461,7 +461,7 @@ Non-nil means always go to the next Octave code line after sending." ;; For (invalid) code between switch and case. ;; (if (smie-rule-parent-p "switch") 4) nil)) - ('(:after . "=") octave-block-offset))) + ('(:after . "=") (smie-rule-parent octave-block-offset)))) (defun octave-indent-comment () "A function for `smie-indent-functions' (which see)." diff --git a/test/lisp/progmodes/octave-tests.el b/test/lisp/progmodes/octave-tests.el new file mode 100644 index 0000000000..e28fe73b83 --- /dev/null +++ b/test/lisp/progmodes/octave-tests.el @@ -0,0 +1,49 @@ +;;; octave-tests.el --- Test suite for octave.el -*- lexical-binding:t -*- + +;; Copyright (C) 2021 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 GNU Emacs. If not, see . + +;;; Commentary: + +;;; Code: + +(require 'ert) +(require 'octave) + +(defun octave-test--indent (string) + (with-temp-buffer + (octave-mode) + (insert string) + (indent-region (point-min) (point-max)) + (buffer-string))) + +(ert-deftest octave-tests--continuation-indentation () + (should + (equal (octave-test--indent "a = b + a * \\ +c; +") + "a = b + a * \\ + c; +")) + (should (equal (octave-test--indent "a = \\ +b; +") + "a = \\ + b; +"))) + +;;; octave-tests.el ends here commit a4c922d84f3fb92cbccc37f69370b016250a88cd Author: Eli Zaretskii Date: Sun May 30 06:11:02 2021 +0200 Clarify indent-line-function doc string * lisp/indent.el (indent-line-function): Clarify by avoiding specifics (bug#20846). diff --git a/lisp/indent.el b/lisp/indent.el index 285b8e2038..a33d962009 100644 --- a/lisp/indent.el +++ b/lisp/indent.el @@ -39,8 +39,8 @@ (defvar indent-line-function 'indent-relative "Function to indent the current line. This function will be called with no arguments. -If it is called somewhere where auto-indentation cannot be done -\(e.g. inside a string), the function should simply return `noindent'. +If it is called somewhere where it cannot auto-indent, the function +should return `noindent' to signal that it didn't. Setting this function is all you need to make TAB indent appropriately. Don't rebind TAB unless you really need to.") commit c97716e9a201c8b5fe0aad414f1846ace878258e Author: Stefan Monnier Date: Sat May 29 14:24:23 2021 -0400 * lisp/mpc.el (mpc-format): Fix inf-loop in constructed predicate diff --git a/lisp/mpc.el b/lisp/mpc.el index f730275038..9addb70f56 100644 --- a/lisp/mpc.el +++ b/lisp/mpc.el @@ -1027,10 +1027,14 @@ If PLAYLIST is t or nil or missing, use the main playlist." (let ((dir (file-name-directory (cdr (assq 'file info))))) ;; (debug) (setq pred - (lambda (info) - (and (funcall pred info) - (equal dir (file-name-directory - (cdr (assq 'file info))))))) + ;; We want the closure to capture the current + ;; value of `pred' and not a reference to the + ;; variable itself. + (let ((oldpred pred)) + (lambda (info) + (and (funcall oldpred info) + (equal dir (file-name-directory + (cdr (assq 'file info)))))))) (if-let* ((covers '(".folder.png" "cover.jpg" "folder.jpg")) (cover (cl-loop for file in (directory-files (mpc-file-local-copy dir)) if (member (downcase file) covers) @@ -1057,9 +1061,13 @@ If PLAYLIST is t or nil or missing, use the main playlist." (when (and (null val) (eq tag 'Title)) (setq val (cdr (assq 'file info)))) (setq pred - (lambda (info) - (and (funcall pred info) - (equal val (cdr (assq ',tag info)))))) + ;; We want the closure to capture the current + ;; value of `pred' and not a reference to the + ;; variable itself. + (let ((oldpred pred)) + (lambda (info) + (and (funcall oldpred info) + (equal val (cdr (assq tag info))))))) (cond ((not (and (eq tag 'Date) (stringp val))) val) ;; For "date", only keep the year! commit 1855e3d0c4f156775ca0a462d3c8154e65481fbd Author: Andreas Schwab Date: Sat May 29 15:35:25 2021 +0200 * lisp/wdired.el (wdired-normalize-filename): Sync with dired-get-filename. (Bug#48659) diff --git a/lisp/wdired.el b/lisp/wdired.el index 35211bcf86..22c1cebe13 100644 --- a/lisp/wdired.el +++ b/lisp/wdired.el @@ -351,13 +351,32 @@ or \\[wdired-abort-changes] to abort changes"))) ;; This code is a copy of some dired-get-filename lines. (defsubst wdired-normalize-filename (file unquotep) (when unquotep - (setq file - ;; FIXME: shouldn't we check for a `b' argument or somesuch before - ;; doing such unquoting? --Stef - (read (concat - "\"" (replace-regexp-in-string - "\\([^\\]\\|\\`\\)\"" "\\1\\\\\"" file) - "\"")))) + ;; Unquote names quoted by ls or by dired-insert-directory. + ;; This code was written using `read' to unquote, because + ;; it's faster than substituting \007 (4 chars) -> ^G (1 + ;; char) etc. in a lisp loop. Unfortunately, this decision + ;; has necessitated hacks such as dealing with filenames + ;; with quotation marks in their names. + (while (string-match "\\(?:[^\\]\\|\\`\\)\\(\"\\)" file) + (setq file (replace-match "\\\"" nil t file 1))) + ;; Unescape any spaces escaped by ls -b (bug#10469). + ;; Other -b quotes, eg \t, \n, work transparently. + (if (dired-switches-escape-p dired-actual-switches) + (let ((start 0) + (rep "") + (shift -1)) + (while (string-match "\\(\\\\\\) " file start) + (setq file (replace-match rep nil t file 1) + start (+ shift (match-end 0)))))) + (when (eq system-type 'windows-nt) + (save-match-data + (let ((start 0)) + (while (string-match "\\\\" file start) + (aset file (match-beginning 0) ?/) + (setq start (match-end 0)))))) + + ;; Hence we don't need to worry about converting `\\' back to `\'. + (setq file (read (concat "\"" file "\"")))) (and file buffer-file-coding-system (not file-name-coding-system) (not default-file-name-coding-system) commit 246a41759c4d2fab1705f40a228260dc5bb55369 Author: Stefan Monnier Date: Sat May 29 09:22:57 2021 -0400 * lisp/electric.el: Do auto-indent inside strings and comments by default This fixes bug#20846 where it transpired that there is no good reason to shy away from auto-indenting inside comments and strings. (electric-indent-post-self-insert-function): Don't check syntax-ppss. diff --git a/etc/NEWS b/etc/NEWS index 49bde94e8d..c6e7084118 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2451,6 +2451,13 @@ similar to prefix arguments, but are more flexible and discoverable. * Incompatible Editing Changes in Emacs 28.1 +** `electric-indent-mode` now also indents inside strings and comments, +(unless the indentation function doesn't, of course). +To recover the previous behavior you can use: + + (add-hook 'electric-indent-functions + (lambda (_) (if (nth 8 (syntax-ppss)) 'no-indent))) + ** The 'M-o' ('facemenu-keymap') global binding has been removed. To restore the old binding, say something like: diff --git a/lisp/electric.el b/lisp/electric.el index 6701a36d8b..4394fae436 100644 --- a/lisp/electric.el +++ b/lisp/electric.el @@ -245,10 +245,7 @@ or comment." 'electric-indent-functions last-command-event) (memq last-command-event electric-indent-chars)))) - (not - (or (memq act '(nil no-indent)) - ;; In a string or comment. - (unless (eq act 'do-indent) (nth 8 (syntax-ppss)))))))) + (not (memq act '(nil no-indent)))))) ;; If we error during indent, silently give up since this is an ;; automatic action that the user didn't explicitly request. ;; But we don't want to suppress errors from elsewhere in *this* commit 4d4c73da5a0aa4233b1dcdcf7db068fc79db6513 Author: Keith David Bershatsky Date: Sat May 29 13:45:59 2021 +0200 Improve tex fontification of quoted strings * lisp/textmodes/tex-mode.el (tex-font-lock-keywords-2): Fontify ``text like this'' that has an apostrophe correctly (bug#16881). diff --git a/lisp/textmodes/tex-mode.el b/lisp/textmodes/tex-mode.el index 8d7f459190..a805c8952f 100644 --- a/lisp/textmodes/tex-mode.el +++ b/lisp/textmodes/tex-mode.el @@ -599,11 +599,13 @@ An alternative value is \" . \", if you use a font with a narrow period." ;; Citation args. (list (concat slash citations opt arg) 3 'font-lock-constant-face) ;; - ;; Text between `` quotes ''. - (cons (concat (regexp-opt '("``" "\"<" "\"`" "<<" "«") t) - "[^'\">{]+" ;a bit pessimistic - (regexp-opt '("''" "\">" "\"'" ">>" "»") t)) - 'font-lock-string-face) + ;; Text between `` quotes ''. + (list (concat (regexp-opt '("``" "\"<" "\"`" "<<" "«") t) + "\\(\\(.\\|\n\\)+?\\)" + (regexp-opt `("''" "\">" "\"'" ">>" "»") t)) + '(1 font-lock-keyword-face) + '(2 font-lock-string-face) + '(4 font-lock-keyword-face)) ;; ;; Command names, special and general. (cons (concat slash specials-1) 'font-lock-warning-face)