aboutsummaryrefslogtreecommitdiffstats
path: root/lisp
diff options
context:
space:
mode:
authorMichael R. Mauger2017-07-24 22:15:04 -0400
committerMichael R. Mauger2017-07-24 22:15:04 -0400
commitdf1a71272e5cdd10b511e2ffd702ca50ddd8a773 (patch)
tree9b9ac725394ee80891e2bff57b6407d0e491e71a /lisp
parenteb27fc4d49e8c914cd0e6a8a2d02159601542141 (diff)
parent32daa3cb54523006c88717cbeac87964cd687a1b (diff)
downloademacs-df1a71272e5cdd10b511e2ffd702ca50ddd8a773.tar.gz
emacs-df1a71272e5cdd10b511e2ffd702ca50ddd8a773.zip
Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs
Diffstat (limited to 'lisp')
-rw-r--r--lisp/calendar/todo-mode.el291
-rw-r--r--lisp/cus-start.el32
-rw-r--r--lisp/dired-aux.el8
-rw-r--r--lisp/dired-x.el8
-rw-r--r--lisp/dired.el13
-rw-r--r--lisp/display-line-numbers.el106
-rw-r--r--lisp/electric.el94
-rw-r--r--lisp/emacs-lisp/bytecomp.el43
-rw-r--r--lisp/emacs-lisp/cl-generic.el16
-rw-r--r--lisp/emacs-lisp/cl-lib.el10
-rw-r--r--lisp/emacs-lisp/edebug.el2
-rw-r--r--lisp/emacs-lisp/eldoc.el49
-rw-r--r--lisp/emacs-lisp/ert.el15
-rw-r--r--lisp/emacs-lisp/gv.el6
-rw-r--r--lisp/emacs-lisp/map.el19
-rw-r--r--lisp/emacs-lisp/nadvice.el12
-rw-r--r--lisp/emacs-lisp/pcase.el1
-rw-r--r--lisp/emacs-lisp/rx.el56
-rw-r--r--lisp/eshell/em-prompt.el15
-rw-r--r--lisp/faces.el34
-rw-r--r--lisp/files.el7
-rw-r--r--lisp/frame.el15
-rw-r--r--lisp/gnus/gnus-sum.el7
-rw-r--r--lisp/help-fns.el1
-rw-r--r--lisp/help.el3
-rw-r--r--lisp/international/characters.el22
-rw-r--r--lisp/international/fontset.el4
-rw-r--r--lisp/international/mule-cmds.el6
-rw-r--r--lisp/kmacro.el11
-rw-r--r--lisp/leim/quail/latin-alt.el16
-rw-r--r--lisp/loadhist.el95
-rw-r--r--lisp/ls-lisp.el6
-rw-r--r--lisp/mail/rmail.el2
-rw-r--r--lisp/menu-bar.el64
-rw-r--r--lisp/net/shr.el3
-rw-r--r--lisp/net/tramp-cache.el12
-rw-r--r--lisp/net/tramp-sh.el7
-rw-r--r--lisp/net/tramp.el12
-rw-r--r--lisp/net/trampver.el6
-rw-r--r--lisp/progmodes/cc-cmds.el27
-rw-r--r--lisp/progmodes/cc-defs.el12
-rw-r--r--lisp/progmodes/cc-engine.el21
-rw-r--r--lisp/progmodes/cc-mode.el66
-rw-r--r--lisp/progmodes/cperl-mode.el4
-rw-r--r--lisp/progmodes/executable.el36
-rw-r--r--lisp/progmodes/grep.el104
-rw-r--r--lisp/progmodes/ld-script.el9
-rw-r--r--lisp/progmodes/perl-mode.el43
-rw-r--r--lisp/progmodes/xref.el33
-rw-r--r--lisp/ses.el232
-rw-r--r--lisp/simple.el21
-rw-r--r--lisp/startup.el1
-rw-r--r--lisp/subr.el12
-rw-r--r--lisp/vc/vc-src.el2
-rw-r--r--lisp/wid-edit.el20
-rw-r--r--lisp/window.el6
56 files changed, 1242 insertions, 536 deletions
diff --git a/lisp/calendar/todo-mode.el b/lisp/calendar/todo-mode.el
index 235eb83e85b..b89c1c2bbd5 100644
--- a/lisp/calendar/todo-mode.el
+++ b/lisp/calendar/todo-mode.el
@@ -1,4 +1,4 @@
1;;; todo-mode.el --- facilities for making and maintaining todo lists 1;;; todo-mode.el --- facilities for making and maintaining todo lists -*- lexical-binding:t -*-
2 2
3;; Copyright (C) 1997, 1999, 2001-2017 Free Software Foundation, Inc. 3;; Copyright (C) 1997, 1999, 2001-2017 Free Software Foundation, Inc.
4 4
@@ -72,14 +72,14 @@ file truenames in `todo-directory' with the extension
72\".todo\". With non-nil ARCHIVES return the list of archive file 72\".todo\". With non-nil ARCHIVES return the list of archive file
73truenames (those with the extension \".toda\")." 73truenames (those with the extension \".toda\")."
74 (let ((files (if (file-exists-p todo-directory) 74 (let ((files (if (file-exists-p todo-directory)
75 (mapcar 'file-truename 75 (mapcar #'file-truename
76 (directory-files todo-directory t 76 (directory-files todo-directory t
77 (if archives "\\.toda$" "\\.todo$") t))))) 77 (if archives "\\.toda\\'" "\\.todo\\'") t)))))
78 (sort files (lambda (s1 s2) (let ((cis1 (upcase s1)) 78 (sort files (lambda (s1 s2) (let ((cis1 (upcase s1))
79 (cis2 (upcase s2))) 79 (cis2 (upcase s2)))
80 (string< cis1 cis2)))))) 80 (string< cis1 cis2))))))
81 81
82(defcustom todo-files-function 'todo-files 82(defcustom todo-files-function #'todo-files
83 "Function returning the value of the variable `todo-files'. 83 "Function returning the value of the variable `todo-files'.
84This function should take an optional argument that, if non-nil, 84This function should take an optional argument that, if non-nil,
85makes it return the value of the variable `todo-archives'." 85makes it return the value of the variable `todo-archives'."
@@ -188,6 +188,15 @@ The final element is \"*\", indicating an unspecified month.")
188 "Array of abbreviated month names, in order. 188 "Array of abbreviated month names, in order.
189The final element is \"*\", indicating an unspecified month.") 189The final element is \"*\", indicating an unspecified month.")
190 190
191(with-no-warnings
192 ;; FIXME: These vars lack a prefix, but this is out of our control, because
193 ;; they're defined by Calendar, e.g. for calendar-date-display-form.
194 (defvar dayname)
195 (defvar monthname)
196 (defvar day)
197 (defvar month)
198 (defvar year))
199
191(defconst todo-date-pattern 200(defconst todo-date-pattern
192 (let ((dayname (diary-name-pattern calendar-day-name-array nil t))) 201 (let ((dayname (diary-name-pattern calendar-day-name-array nil t)))
193 (concat "\\(?4:\\(?5:" dayname "\\)\\|" 202 (concat "\\(?4:\\(?5:" dayname "\\)\\|"
@@ -198,7 +207,7 @@ The final element is \"*\", indicating an unspecified month.")
198 (month "\\(?7:[0-9]+\\|\\*\\)") 207 (month "\\(?7:[0-9]+\\|\\*\\)")
199 (day "\\(?8:[0-9]+\\|\\*\\)") 208 (day "\\(?8:[0-9]+\\|\\*\\)")
200 (year "-?\\(?9:[0-9]+\\|\\*\\)")) 209 (year "-?\\(?9:[0-9]+\\|\\*\\)"))
201 (mapconcat 'eval calendar-date-display-form "")) 210 (mapconcat #'eval calendar-date-display-form ""))
202 "\\)")) 211 "\\)"))
203 "Regular expression matching a todo item date header.") 212 "Regular expression matching a todo item date header.")
204 213
@@ -260,7 +269,7 @@ This function is the value of the user variable
260 (let ((file (todo-short-file-name todo-current-todo-file))) 269 (let ((file (todo-short-file-name todo-current-todo-file)))
261 (format "%s category %d: %s" file todo-category-number cat))) 270 (format "%s category %d: %s" file todo-category-number cat)))
262 271
263(defcustom todo-mode-line-function 'todo-mode-line-control 272(defcustom todo-mode-line-function #'todo-mode-line-control
264 "Function that returns a mode line control for Todo mode buffers. 273 "Function that returns a mode line control for Todo mode buffers.
265The function expects one argument holding the name of the current 274The function expects one argument holding the name of the current
266todo category. The resulting control becomes the local value of 275todo category. The resulting control becomes the local value of
@@ -555,13 +564,15 @@ This lacks the extension and directory components."
555 (when (stringp file) 564 (when (stringp file)
556 (file-name-sans-extension (file-name-nondirectory file)))) 565 (file-name-sans-extension (file-name-nondirectory file))))
557 566
567(defun todo--files-type-list ()
568 (mapcar (lambda (f) (list 'const (todo-short-file-name f)))
569 (funcall todo-files-function)))
570
558(defcustom todo-default-todo-file (todo-short-file-name 571(defcustom todo-default-todo-file (todo-short-file-name
559 (car (funcall todo-files-function))) 572 (car (funcall todo-files-function)))
560 "Todo file visited by first session invocation of `todo-show'." 573 "Todo file visited by first session invocation of `todo-show'."
561 :type (when todo-files 574 :type (when todo-files
562 `(radio ,@(mapcar (lambda (f) (list 'const f)) 575 `(radio ,@(todo--files-type-list)))
563 (mapcar 'todo-short-file-name
564 (funcall todo-files-function)))))
565 :group 'todo) 576 :group 'todo)
566 577
567(defcustom todo-show-current-file t 578(defcustom todo-show-current-file t
@@ -598,9 +609,7 @@ Otherwise, `todo-show' always visits `todo-default-todo-file'."
598 609
599(defcustom todo-category-completions-files nil 610(defcustom todo-category-completions-files nil
600 "List of files for building `todo-read-category' completions." 611 "List of files for building `todo-read-category' completions."
601 :type `(set ,@(mapcar (lambda (f) (list 'const f)) 612 :type `(set ,@(todo--files-type-list))
602 (mapcar 'todo-short-file-name
603 (funcall todo-files-function))))
604 :group 'todo) 613 :group 'todo)
605 614
606(defcustom todo-completion-ignore-case nil 615(defcustom todo-completion-ignore-case nil
@@ -707,11 +716,12 @@ and done items are always shown on visiting a category."
707 (let ((rxfiles (directory-files todo-directory t 716 (let ((rxfiles (directory-files todo-directory t
708 ".*\\.todr$" t))) 717 ".*\\.todr$" t)))
709 (when (and rxfiles (> (length rxfiles) 1)) 718 (when (and rxfiles (> (length rxfiles) 1))
710 (let ((rxf (mapcar 'todo-short-file-name rxfiles))) 719 (let ((rxf (mapcar #'todo-short-file-name rxfiles)))
711 (setq fi-file (todo-absolute-file-name 720 (setq fi-file (todo-absolute-file-name
712 (completing-read 721 (completing-read
713 "Choose a regexp items file: " 722 "Choose a regexp items file: "
714 rxf) 'regexp)))))) 723 rxf)
724 'regexp))))))
715 (if (file-exists-p fi-file) 725 (if (file-exists-p fi-file)
716 (progn 726 (progn
717 (set-window-buffer 727 (set-window-buffer
@@ -823,7 +833,7 @@ buries it and restores state as needed."
823 (when (buffer-live-p buf) (kill-buffer buf))) 833 (when (buffer-live-p buf) (kill-buffer buf)))
824 ((eq major-mode 'todo-mode) 834 ((eq major-mode 'todo-mode)
825 (todo-save) 835 (todo-save)
826 (bury-buffer))))) 836 (quit-window)))))
827 837
828;; ----------------------------------------------------------------------------- 838;; -----------------------------------------------------------------------------
829;;; Navigation between and within categories 839;;; Navigation between and within categories
@@ -857,7 +867,7 @@ category is the first)."
857 (zerop (todo-get-count 'done)) 867 (zerop (todo-get-count 'done))
858 (not (zerop (todo-get-count 'archived)))) 868 (not (zerop (todo-get-count 'archived))))
859 (setq todo-category-number 869 (setq todo-category-number
860 (apply (if back '1- '1+) (list todo-category-number))))) 870 (funcall (if back #'1- #'1+) todo-category-number))))
861 (todo-category-select) 871 (todo-category-select)
862 (goto-char (point-min))) 872 (goto-char (point-min)))
863 873
@@ -1117,7 +1127,8 @@ these files, also rename them accordingly."
1117 (snname (todo-short-file-name nname)) 1127 (snname (todo-short-file-name nname))
1118 (files (directory-files todo-directory t 1128 (files (directory-files todo-directory t
1119 (concat ".*" (regexp-quote soname) 1129 (concat ".*" (regexp-quote soname)
1120 ".*\\.tod[aorty]$") t))) 1130 ".*\\.tod[aorty]$")
1131 t)))
1121 (dolist (f files) 1132 (dolist (f files)
1122 (let* ((sfname (todo-short-file-name f)) 1133 (let* ((sfname (todo-short-file-name f))
1123 (fext (file-name-extension f t)) 1134 (fext (file-name-extension f t))
@@ -1363,10 +1374,12 @@ todo or done items."
1363 (let ((buffer-read-only) 1374 (let ((buffer-read-only)
1364 (beg (re-search-backward 1375 (beg (re-search-backward
1365 (concat "^" (regexp-quote (concat todo-category-beg cat)) 1376 (concat "^" (regexp-quote (concat todo-category-beg cat))
1366 "\n") nil t)) 1377 "\n")
1378 nil t))
1367 (end (if (re-search-forward 1379 (end (if (re-search-forward
1368 (concat "\n\\(" (regexp-quote todo-category-beg) 1380 (concat "\n\\(" (regexp-quote todo-category-beg)
1369 ".*\n\\)") nil t) 1381 ".*\n\\)")
1382 nil t)
1370 (match-beginning 1) 1383 (match-beginning 1)
1371 (point-max)))) 1384 (point-max))))
1372 (remove-overlays beg end) 1385 (remove-overlays beg end)
@@ -1475,7 +1488,8 @@ the archive of the file moved to, creating it if it does not exist."
1475 (goto-char (point-max)) 1488 (goto-char (point-max))
1476 (re-search-backward 1489 (re-search-backward
1477 (concat "^" (regexp-quote todo-category-beg) 1490 (concat "^" (regexp-quote todo-category-beg)
1478 "\\(" (regexp-quote cat) "\\)$") nil t) 1491 "\\(" (regexp-quote cat) "\\)$")
1492 nil t)
1479 (replace-match new nil nil nil 1)) 1493 (replace-match new nil nil nil 1))
1480 (setq todo-categories 1494 (setq todo-categories
1481 (append todo-categories (list (cons (or new cat) counts)))) 1495 (append todo-categories (list (cons (or new cat) counts))))
@@ -1746,7 +1760,7 @@ consist of the the last todo items and the first done items."
1746 (let ((cat (todo-current-category))) 1760 (let ((cat (todo-current-category)))
1747 (unless (> n 1) (setq n 1)) 1761 (unless (> n 1) (setq n 1))
1748 (catch 'end 1762 (catch 'end
1749 (dotimes (i n) 1763 (dotimes (_ n)
1750 (let* ((marks (assoc cat todo-categories-with-marks)) 1764 (let* ((marks (assoc cat todo-categories-with-marks))
1751 (ov (progn 1765 (ov (progn
1752 (unless (looking-at todo-item-start) 1766 (unless (looking-at todo-item-start)
@@ -2134,7 +2148,8 @@ the item at point."
2134 (todo-item-start) 2148 (todo-item-start)
2135 (re-search-forward 2149 (re-search-forward
2136 (concat " \\[" (regexp-quote todo-comment-string) 2150 (concat " \\[" (regexp-quote todo-comment-string)
2137 ": \\([^]]+\\)\\]") end t))) 2151 ": \\([^]]+\\)\\]")
2152 end t)))
2138 (prompt (if comment "Edit comment: " "Enter a comment: ")) 2153 (prompt (if comment "Edit comment: " "Enter a comment: "))
2139 (buffer-read-only nil)) 2154 (buffer-read-only nil))
2140 ;; When there are marked items, user can invoke todo-edit-item 2155 ;; When there are marked items, user can invoke todo-edit-item
@@ -2150,7 +2165,8 @@ the item at point."
2150 (todo-item-start) 2165 (todo-item-start)
2151 (if (re-search-forward (concat " \\[" 2166 (if (re-search-forward (concat " \\["
2152 (regexp-quote todo-comment-string) 2167 (regexp-quote todo-comment-string)
2153 ": \\([^]]+\\)\\]") end t) 2168 ": \\([^]]+\\)\\]")
2169 end t)
2154 (if comment-delete 2170 (if comment-delete
2155 (when (todo-y-or-n-p "Delete comment? ") 2171 (when (todo-y-or-n-p "Delete comment? ")
2156 (delete-region (match-beginning 0) (match-end 0))) 2172 (delete-region (match-beginning 0) (match-end 0)))
@@ -2182,7 +2198,8 @@ the item at point."
2182 (cons item 0)))))) 2198 (cons item 0))))))
2183 (when include-header 2199 (when include-header
2184 (while (not (string-match (concat todo-date-string-start 2200 (while (not (string-match (concat todo-date-string-start
2185 todo-date-pattern) new)) 2201 todo-date-pattern)
2202 new))
2186 (setq new (read-from-minibuffer 2203 (setq new (read-from-minibuffer
2187 "Item must start with a date: " new)))) 2204 "Item must start with a date: " new))))
2188 ;; Ensure lines following hard newlines are indented. 2205 ;; Ensure lines following hard newlines are indented.
@@ -2211,7 +2228,8 @@ made in the number or names of categories."
2211 (regex "\\(\n\\)[^[:blank:]]") 2228 (regex "\\(\n\\)[^[:blank:]]")
2212 (buf (buffer-base-buffer))) 2229 (buf (buffer-base-buffer)))
2213 (while (not (string-match (concat todo-date-string-start 2230 (while (not (string-match (concat todo-date-string-start
2214 todo-date-pattern) item)) 2231 todo-date-pattern)
2232 item))
2215 (setq item (read-from-minibuffer 2233 (setq item (read-from-minibuffer
2216 "Item must start with a date: " item))) 2234 "Item must start with a date: " item)))
2217 ;; Ensure lines following hard newlines are indented. 2235 ;; Ensure lines following hard newlines are indented.
@@ -2270,8 +2288,7 @@ made in the number or names of categories."
2270 "\\)\\(?2: " diary-time-regexp "\\)?" 2288 "\\)\\(?2: " diary-time-regexp "\\)?"
2271 (regexp-quote todo-nondiary-end) "?") 2289 (regexp-quote todo-nondiary-end) "?")
2272 (line-end-position) t) 2290 (line-end-position) t)
2273 (let* ((odate (match-string-no-properties 1)) 2291 (let* ((otime (match-string-no-properties 2))
2274 (otime (match-string-no-properties 2))
2275 (odayname (match-string-no-properties 5)) 2292 (odayname (match-string-no-properties 5))
2276 (omonthname (match-string-no-properties 6)) 2293 (omonthname (match-string-no-properties 6))
2277 (omonth (match-string-no-properties 7)) 2294 (omonth (match-string-no-properties 7))
@@ -2382,7 +2399,8 @@ made in the number or names of categories."
2382 (calendar-current-date)))) 2399 (calendar-current-date))))
2383 (date (calendar-gregorian-from-absolute 2400 (date (calendar-gregorian-from-absolute
2384 (+ (calendar-absolute-from-gregorian 2401 (+ (calendar-absolute-from-gregorian
2385 (list mm dd yy)) inc))) 2402 (list mm dd yy))
2403 inc)))
2386 (adjmm (nth 0 date))) 2404 (adjmm (nth 0 date)))
2387 ;; Set year and month(name) to adjusted values. 2405 ;; Set year and month(name) to adjusted values.
2388 (unless (string= year "*") 2406 (unless (string= year "*")
@@ -2396,7 +2414,7 @@ made in the number or names of categories."
2396 ;; If year, month or day date string components were 2414 ;; If year, month or day date string components were
2397 ;; changed, rebuild the date string. 2415 ;; changed, rebuild the date string.
2398 (when (memq what '(year month day)) 2416 (when (memq what '(year month day))
2399 (setq ndate (mapconcat 'eval calendar-date-display-form "")))) 2417 (setq ndate (mapconcat #'eval calendar-date-display-form ""))))
2400 (when ndate (replace-match ndate nil nil nil 1)) 2418 (when ndate (replace-match ndate nil nil nil 1))
2401 ;; Add new time string to the header, if it was supplied. 2419 ;; Add new time string to the header, if it was supplied.
2402 (when ntime 2420 (when ntime
@@ -2423,7 +2441,7 @@ made in the number or names of categories."
2423 (when marked (goto-char (point-min))) 2441 (when marked (goto-char (point-min)))
2424 (while (not (eobp)) 2442 (while (not (eobp))
2425 (unless (and marked (not (todo-marked-item-p))) 2443 (unless (and marked (not (todo-marked-item-p)))
2426 (let* ((beg (todo-item-start)) 2444 (let* ((_beg (todo-item-start))
2427 (lim (save-excursion (todo-item-end))) 2445 (lim (save-excursion (todo-item-end)))
2428 (end (save-excursion 2446 (end (save-excursion
2429 (or (todo-time-string-matcher lim) 2447 (or (todo-time-string-matcher lim)
@@ -2470,7 +2488,7 @@ items."
2470 (while (not (eobp)) 2488 (while (not (eobp))
2471 (if (todo-done-item-p) ; We've gone too far. 2489 (if (todo-done-item-p) ; We've gone too far.
2472 (throw 'stop nil) 2490 (throw 'stop nil)
2473 (let* ((beg (todo-item-start)) 2491 (let* ((_beg (todo-item-start))
2474 (lim (save-excursion (todo-item-end))) 2492 (lim (save-excursion (todo-item-end)))
2475 (end (save-excursion 2493 (end (save-excursion
2476 (or (todo-time-string-matcher lim) 2494 (or (todo-time-string-matcher lim)
@@ -2682,9 +2700,7 @@ section in the category moved to."
2682 (not marked)) 2700 (not marked))
2683 (let* ((buffer-read-only) 2701 (let* ((buffer-read-only)
2684 (file1 todo-current-todo-file) 2702 (file1 todo-current-todo-file)
2685 (num todo-category-number)
2686 (item (todo-item-string)) 2703 (item (todo-item-string))
2687 (diary-item (todo-diary-item-p))
2688 (done-item (and (todo-done-item-p) item)) 2704 (done-item (and (todo-done-item-p) item))
2689 (omark (save-excursion (todo-item-start) (point-marker))) 2705 (omark (save-excursion (todo-item-start) (point-marker)))
2690 (todo 0) 2706 (todo 0)
@@ -2956,7 +2972,8 @@ comments without asking."
2956 ;; affirmed, omit subsequent comments without asking. 2972 ;; affirmed, omit subsequent comments without asking.
2957 (when (re-search-forward 2973 (when (re-search-forward
2958 (concat " \\[" (regexp-quote todo-comment-string) 2974 (concat " \\[" (regexp-quote todo-comment-string)
2959 ": [^]]+\\]") end t) 2975 ": [^]]+\\]")
2976 end t)
2960 (unwind-protect 2977 (unwind-protect
2961 (if (eq first 'first) 2978 (if (eq first 'first)
2962 (setq first 2979 (setq first
@@ -3216,7 +3233,8 @@ the only category in the archive, the archive file is deleted."
3216 (let* ((cat (todo-current-category)) 3233 (let* ((cat (todo-current-category))
3217 (tbuf (find-file-noselect 3234 (tbuf (find-file-noselect
3218 (concat (file-name-sans-extension todo-current-todo-file) 3235 (concat (file-name-sans-extension todo-current-todo-file)
3219 ".todo") t)) 3236 ".todo")
3237 t))
3220 (marked (assoc cat todo-categories-with-marks)) 3238 (marked (assoc cat todo-categories-with-marks))
3221 (item (concat (todo-item-string) "\n")) 3239 (item (concat (todo-item-string) "\n"))
3222 (marked-count 0) 3240 (marked-count 0)
@@ -3241,7 +3259,8 @@ the only category in the archive, the archive file is deleted."
3241 ;; one, add it. 3259 ;; one, add it.
3242 (unless (re-search-forward 3260 (unless (re-search-forward
3243 (concat "^" (regexp-quote (concat todo-category-beg cat)) 3261 (concat "^" (regexp-quote (concat todo-category-beg cat))
3244 "$") nil t) 3262 "$")
3263 nil t)
3245 (todo-add-category nil cat) 3264 (todo-add-category nil cat)
3246 (setq newcat t)) 3265 (setq newcat t))
3247 ;; Go to top of category's done section. 3266 ;; Go to top of category's done section.
@@ -3449,9 +3468,9 @@ decreasing or increasing its number."
3449 (unless prompt (setq priority candidate))) 3468 (unless prompt (setq priority candidate)))
3450 (let* ((lower (< curnum priority)) ; Priority is being lowered. 3469 (let* ((lower (< curnum priority)) ; Priority is being lowered.
3451 (head (butlast todo-categories 3470 (head (butlast todo-categories
3452 (apply (if lower 'identity '1+) 3471 (funcall (if lower #'identity #'1+)
3453 (list (- maxnum priority))))) 3472 (- maxnum priority))))
3454 (tail (nthcdr (apply (if lower 'identity '1-) (list priority)) 3473 (tail (nthcdr (funcall (if lower #'identity #'1-) priority)
3455 todo-categories)) 3474 todo-categories))
3456 ;; Category's name and items counts list. 3475 ;; Category's name and items counts list.
3457 (catcons (nth (1- curnum) todo-categories)) 3476 (catcons (nth (1- curnum) todo-categories))
@@ -3537,7 +3556,7 @@ decreasing or increasing its number."
3537 "Return adjusted length of category label button. 3556 "Return adjusted length of category label button.
3538The adjustment ensures proper tabular alignment in Todo 3557The adjustment ensures proper tabular alignment in Todo
3539Categories mode." 3558Categories mode."
3540 (let* ((categories (mapcar 'car todo-categories)) 3559 (let* ((categories (mapcar #'car todo-categories))
3541 (longest (todo-longest-category-name-length categories)) 3560 (longest (todo-longest-category-name-length categories))
3542 (catlablen (length todo-categories-category-label)) 3561 (catlablen (length todo-categories-category-label))
3543 (lc-diff (- longest catlablen))) 3562 (lc-diff (- longest catlablen)))
@@ -3623,24 +3642,24 @@ LABEL determines which type of count is sorted."
3623 ov) 3642 ov)
3624 (insert-button str 'face nil 3643 (insert-button str 'face nil
3625 'action 3644 'action
3626 `(lambda (button) 3645 (lambda (_button)
3627 (let ((key (todo-label-to-key ,label))) 3646 (let ((key (todo-label-to-key label)))
3628 (if (and (member key todo-descending-counts) 3647 (if (and (member key todo-descending-counts)
3629 (eq key 'alpha)) 3648 (eq key 'alpha))
3630 (progn 3649 (progn
3631 ;; If display is alphabetical, switch back to 3650 ;; If display is alphabetical, switch back to
3632 ;; category priority order. 3651 ;; category priority order.
3633 (todo-display-sorted nil) 3652 (todo-display-sorted nil)
3634 (setq todo-descending-counts 3653 (setq todo-descending-counts
3635 (delete key todo-descending-counts))) 3654 (delete key todo-descending-counts)))
3636 (todo-display-sorted key))))) 3655 (todo-display-sorted key)))))
3637 (setq ov (make-overlay beg end)) 3656 (setq ov (make-overlay beg end))
3638 (overlay-put ov 'face 'todo-button))) 3657 (overlay-put ov 'face 'todo-button)))
3639 3658
3640(defun todo-total-item-counts () 3659(defun todo-total-item-counts ()
3641 "Return a list of total item counts for the current file." 3660 "Return a list of total item counts for the current file."
3642 (mapcar (lambda (i) (apply '+ (mapcar (lambda (l) (aref l i)) 3661 (mapcar (lambda (i) (apply #'+ (mapcar (lambda (x) (aref (cdr x) i))
3643 (mapcar 'cdr todo-categories)))) 3662 todo-categories)))
3644 (list 0 1 2 3))) 3663 (list 0 1 2 3)))
3645 3664
3646(defvar todo-categories-category-number 0 3665(defvar todo-categories-category-number 0
@@ -3685,9 +3704,10 @@ which is the value of the user option
3685 (not (zerop (todo-get-count 'archived cat)))) 3704 (not (zerop (todo-get-count 'archived cat))))
3686 'todo-archived-only 3705 'todo-archived-only
3687 nil) 3706 nil)
3688 'action `(lambda (button) (let ((buf (current-buffer))) 3707 'action (lambda (_button)
3689 (todo-jump-to-category nil ,cat) 3708 (let ((buf (current-buffer)))
3690 (kill-buffer buf)))) 3709 (todo-jump-to-category nil cat)
3710 (kill-buffer buf))))
3691 ;; Highlight the sorted count column. 3711 ;; Highlight the sorted count column.
3692 (let* ((beg (+ opoint 7 (length str))) 3712 (let* ((beg (+ opoint 7 (length str)))
3693 end ovl) 3713 end ovl)
@@ -3766,8 +3786,8 @@ which is the value of the user option
3766 (delete-region (point) (point-max)) 3786 (delete-region (point) (point-max))
3767 ;; Fill in the table with buttonized lines, each showing a category and 3787 ;; Fill in the table with buttonized lines, each showing a category and
3768 ;; its item counts. 3788 ;; its item counts.
3769 (mapc (lambda (cat) (todo-insert-category-line cat sortkey)) 3789 (dolist (cat cats)
3770 (mapcar 'car cats)) 3790 (todo-insert-category-line (car cat) sortkey))
3771 (newline) 3791 (newline)
3772 ;; Add a line showing item count totals. 3792 ;; Add a line showing item count totals.
3773 (insert (make-string (+ 4 (length todo-categories-number-separator)) 32) 3793 (insert (make-string (+ 4 (length todo-categories-number-separator)) 32)
@@ -3823,7 +3843,8 @@ face."
3823 (when (looking-at todo-done-string-start) 3843 (when (looking-at todo-done-string-start)
3824 (setq in-done t)) 3844 (setq in-done t))
3825 (re-search-backward (concat "^" (regexp-quote todo-category-beg) 3845 (re-search-backward (concat "^" (regexp-quote todo-category-beg)
3826 "\\(.*\\)\n") nil t) 3846 "\\(.*\\)\n")
3847 nil t)
3827 (setq cat (match-string-no-properties 1)) 3848 (setq cat (match-string-no-properties 1))
3828 (todo-category-number cat) 3849 (todo-category-number cat)
3829 (todo-category-select) 3850 (todo-category-select)
@@ -3885,9 +3906,7 @@ This variable should be set interactively by
3885 3906
3886(defcustom todo-filter-files nil 3907(defcustom todo-filter-files nil
3887 "List of default files for multifile item filtering." 3908 "List of default files for multifile item filtering."
3888 :type `(set ,@(mapcar (lambda (f) (list 'const f)) 3909 :type `(set ,@(todo--files-type-list))
3889 (mapcar 'todo-short-file-name
3890 (funcall todo-files-function))))
3891 :group 'todo-filtered) 3910 :group 'todo-filtered)
3892 3911
3893(defcustom todo-filter-done-items nil 3912(defcustom todo-filter-done-items nil
@@ -4067,19 +4086,17 @@ regexp items."
4067 (widget-insert "Select files for generating the top priorities list.\n\n") 4086 (widget-insert "Select files for generating the top priorities list.\n\n")
4068 (setq todo-multiple-filter-files-widget 4087 (setq todo-multiple-filter-files-widget
4069 (widget-create 4088 (widget-create
4070 `(set ,@(mapcar (lambda (x) (list 'const x)) 4089 `(set ,@(todo--files-type-list))))
4071 (mapcar 'todo-short-file-name
4072 (funcall todo-files-function))))))
4073 (widget-insert "\n") 4090 (widget-insert "\n")
4074 (widget-create 'push-button 4091 (widget-create 'push-button
4075 :notify (lambda (widget &rest ignore) 4092 :notify (lambda (&rest _)
4076 (setq todo-multiple-filter-files 'quit) 4093 (setq todo-multiple-filter-files 'quit)
4077 (quit-window t) 4094 (quit-window t)
4078 (exit-recursive-edit)) 4095 (exit-recursive-edit))
4079 "Cancel") 4096 "Cancel")
4080 (widget-insert " ") 4097 (widget-insert " ")
4081 (widget-create 'push-button 4098 (widget-create 'push-button
4082 :notify (lambda (&rest ignore) 4099 :notify (lambda (&rest _)
4083 (setq todo-multiple-filter-files 4100 (setq todo-multiple-filter-files
4084 (mapcar (lambda (f) 4101 (mapcar (lambda (f)
4085 (file-truename 4102 (file-truename
@@ -4137,7 +4154,7 @@ multifile commands for further details."
4137 ;; Pressed `cancel' in t-m-f-f file selection dialog. 4154 ;; Pressed `cancel' in t-m-f-f file selection dialog.
4138 (keyboard-quit) 4155 (keyboard-quit)
4139 (concat todo-directory 4156 (concat todo-directory
4140 (mapconcat 'todo-short-file-name flist "-") 4157 (mapconcat #'todo-short-file-name flist "-")
4141 (cond (top ".todt") 4158 (cond (top ".todt")
4142 (diary ".tody") 4159 (diary ".tody")
4143 (regexp ".todr"))))) 4160 (regexp ".todr")))))
@@ -4150,10 +4167,11 @@ multifile commands for further details."
4150 (todo-filter-items-1 (cons 'top new) flist)) 4167 (todo-filter-items-1 (cons 'top new) flist))
4151 ((and (not new) file-exists) 4168 ((and (not new) file-exists)
4152 (when (and rxfiles (> (length rxfiles) 1)) 4169 (when (and rxfiles (> (length rxfiles) 1))
4153 (let ((rxf (mapcar 'todo-short-file-name rxfiles))) 4170 (let ((rxf (mapcar #'todo-short-file-name rxfiles)))
4154 (setq fname (todo-absolute-file-name 4171 (setq fname (todo-absolute-file-name
4155 (completing-read "Choose a regexp items file: " 4172 (completing-read "Choose a regexp items file: "
4156 rxf) 'regexp)))) 4173 rxf)
4174 'regexp))))
4157 (find-file fname) 4175 (find-file fname)
4158 (unless (derived-mode-p 'todo-filtered-items-mode) 4176 (unless (derived-mode-p 'todo-filtered-items-mode)
4159 (todo-filtered-items-mode)) 4177 (todo-filtered-items-mode))
@@ -4164,12 +4182,13 @@ multifile commands for further details."
4164 (dolist (s (split-string (todo-short-file-name fname) "-")) 4182 (dolist (s (split-string (todo-short-file-name fname) "-"))
4165 (setq bufname (if bufname 4183 (setq bufname (if bufname
4166 (concat bufname (if (member s (mapcar 4184 (concat bufname (if (member s (mapcar
4167 'todo-short-file-name 4185 #'todo-short-file-name
4168 todo-files)) 4186 todo-files))
4169 ", " "-") s) 4187 ", " "-")
4188 s)
4170 s))) 4189 s)))
4171 (rename-buffer (format (concat "%s for file" (if multi "s" "") 4190 (rename-buffer (format (concat "%s for file" (if multi "s" "") " \"%s\"")
4172 " \"%s\"") buf bufname)))) 4191 buf bufname))))
4173 4192
4174(defun todo-filter-items-1 (filter file-list) 4193(defun todo-filter-items-1 (filter file-list)
4175 "Build a list of items by applying FILTER to FILE-LIST. 4194 "Build a list of items by applying FILTER to FILE-LIST.
@@ -4235,7 +4254,8 @@ the values of FILTER and FILE-LIST."
4235 todo-top-priorities))) 4254 todo-top-priorities)))
4236 (while (re-search-forward 4255 (while (re-search-forward
4237 (concat "^" (regexp-quote todo-category-beg) 4256 (concat "^" (regexp-quote todo-category-beg)
4238 "\\(.+\\)\n") nil t) 4257 "\\(.+\\)\n")
4258 nil t)
4239 (setq cat (match-string 1)) 4259 (setq cat (match-string 1))
4240 (let (cnum) 4260 (let (cnum)
4241 ;; Unless the number of top priorities to show was 4261 ;; Unless the number of top priorities to show was
@@ -4389,7 +4409,8 @@ its priority has changed, and `same' otherwise."
4389 "\\]" 4409 "\\]"
4390 (regexp-quote todo-nondiary-end)) "?" 4410 (regexp-quote todo-nondiary-end)) "?"
4391 "\\(?4: \\[\\(?3:(archive) \\)?\\(?2:.*:\\)?" 4411 "\\(?4: \\[\\(?3:(archive) \\)?\\(?2:.*:\\)?"
4392 "\\(?1:.*\\)\\]\\).*$") str) 4412 "\\(?1:.*\\)\\]\\).*$")
4413 str)
4393 (let ((cat (match-string 1 str)) 4414 (let ((cat (match-string 1 str))
4394 (file (match-string 2 str)) 4415 (file (match-string 2 str))
4395 (archive (string= (match-string 3 str) "(archive) ")) 4416 (archive (string= (match-string 3 str) "(archive) "))
@@ -4504,8 +4525,13 @@ If the file already exists, overwrite it only on confirmation."
4504;;; Printing Todo mode buffers 4525;;; Printing Todo mode buffers
4505;; ----------------------------------------------------------------------------- 4526;; -----------------------------------------------------------------------------
4506 4527
4507(defcustom todo-print-buffer-function 'ps-print-buffer-with-faces 4528(defcustom todo-print-buffer-function #'ps-print-buffer-with-faces
4508 "Function called by the command `todo-print-buffer'." 4529 "Function called by `todo-print-buffer' to print Todo mode buffers.
4530The function should take an optional argument whose non-nil value
4531is a string naming a file to save the print image to; calling
4532`todo-print-buffer-to-file' prompts for the file name, which is
4533passed to this function. Calling this function with no or a nil
4534argument sends the image to the printer."
4509 :type 'symbol 4535 :type 'symbol
4510 :group 'todo) 4536 :group 'todo)
4511 4537
@@ -4531,8 +4557,7 @@ otherwise, send it to the default printer."
4531 'face 'todo-prefix-string)) 4557 'face 'todo-prefix-string))
4532 (num 0) 4558 (num 0)
4533 (fill-prefix (make-string todo-indent-to-here 32)) 4559 (fill-prefix (make-string todo-indent-to-here 32))
4534 (content (buffer-string)) 4560 (content (buffer-string)))
4535 file)
4536 (with-current-buffer (get-buffer-create buf) 4561 (with-current-buffer (get-buffer-create buf)
4537 (insert content) 4562 (insert content)
4538 (goto-char (point-min)) 4563 (goto-char (point-min))
@@ -4556,10 +4581,9 @@ otherwise, send it to the default printer."
4556 (goto-char (point-min)) 4581 (goto-char (point-min))
4557 (insert header) 4582 (insert header)
4558 (newline 2) 4583 (newline 2)
4559 (if to-file 4584 (funcall todo-print-buffer-function
4560 (let ((file (read-file-name "Print to file: "))) 4585 (if to-file nil
4561 (funcall todo-print-buffer-function file)) 4586 (read-file-name "Print to file: "))))
4562 (funcall todo-print-buffer-function)))
4563 (kill-buffer buf))) 4587 (kill-buffer buf)))
4564 4588
4565(defun todo-print-buffer-to-file () 4589(defun todo-print-buffer-to-file ()
@@ -4596,7 +4620,7 @@ Helper function for `todo-convert-legacy-files'."
4596 (time (match-string 4)) 4620 (time (match-string 4))
4597 dayname) 4621 dayname)
4598 (replace-match "") 4622 (replace-match "")
4599 (insert (mapconcat 'eval calendar-date-display-form "") 4623 (insert (mapconcat #'eval calendar-date-display-form "")
4600 (when time (concat " " time))))) 4624 (when time (concat " " time)))))
4601 4625
4602(defun todo-convert-legacy-files () 4626(defun todo-convert-legacy-files ()
@@ -4720,7 +4744,8 @@ name in `todo-directory'. See also the documentation string of
4720 (unless (save-excursion 4744 (unless (save-excursion
4721 (re-search-backward 4745 (re-search-backward
4722 (concat "^" (regexp-quote todo-category-beg) 4746 (concat "^" (regexp-quote todo-category-beg)
4723 "\\(.*\\)$") nil t) 4747 "\\(.*\\)$")
4748 nil t)
4724 (string= (match-string 1) cat)) 4749 (string= (match-string 1) cat))
4725 ;; Else move it to its category. 4750 ;; Else move it to its category.
4726 (setq item (buffer-substring-no-properties beg end)) 4751 (setq item (buffer-substring-no-properties beg end))
@@ -4734,7 +4759,8 @@ name in `todo-directory'. See also the documentation string of
4734 (forward-line) 4759 (forward-line)
4735 (if (re-search-forward 4760 (if (re-search-forward
4736 (concat "^" (regexp-quote todo-category-beg) 4761 (concat "^" (regexp-quote todo-category-beg)
4737 "\\(.*\\)$") nil t) 4762 "\\(.*\\)$")
4763 nil t)
4738 (progn (goto-char (match-beginning 0)) 4764 (progn (goto-char (match-beginning 0))
4739 (newline) 4765 (newline)
4740 (forward-line -1)) 4766 (forward-line -1))
@@ -4828,10 +4854,7 @@ buffer, clean up the state and return nil."
4828 (setq todo-files (funcall todo-files-function)) 4854 (setq todo-files (funcall todo-files-function))
4829 (setq todo-archives (funcall todo-files-function t)) 4855 (setq todo-archives (funcall todo-files-function t))
4830 t) 4856 t)
4831 (let* ((files (append todo-files todo-archives)) 4857 (let* ((files (append todo-files todo-archives)))
4832 (tctf todo-current-todo-file)
4833 (tgctf todo-global-current-todo-file)
4834 (tdtf (todo-absolute-file-name todo-default-todo-file)))
4835 (unless (or (not todo-current-todo-file) 4858 (unless (or (not todo-current-todo-file)
4836 (member todo-current-todo-file files)) 4859 (member todo-current-todo-file files))
4837 (setq todo-current-todo-file nil)) 4860 (setq todo-current-todo-file nil))
@@ -4850,7 +4873,7 @@ buffer, clean up the state and return nil."
4850 "Return the number of category CAT in this todo file. 4873 "Return the number of category CAT in this todo file.
4851The buffer-local variable `todo-category-number' holds this 4874The buffer-local variable `todo-category-number' holds this
4852number as its value." 4875number as its value."
4853 (let ((categories (mapcar 'car todo-categories))) 4876 (let ((categories (mapcar #'car todo-categories)))
4854 (setq todo-category-number 4877 (setq todo-category-number
4855 ;; Increment by one, so that the number of the first 4878 ;; Increment by one, so that the number of the first
4856 ;; category is one rather than zero. 4879 ;; category is one rather than zero.
@@ -4880,7 +4903,8 @@ number as its value."
4880 (todo-prefix-overlays) 4903 (todo-prefix-overlays)
4881 (goto-char (point-min)) 4904 (goto-char (point-min))
4882 (if (re-search-forward (concat "\n\\(" (regexp-quote todo-category-done) 4905 (if (re-search-forward (concat "\n\\(" (regexp-quote todo-category-done)
4883 "\\)") nil t) 4906 "\\)")
4907 nil t)
4884 (progn 4908 (progn
4885 (setq done-start (match-beginning 0)) 4909 (setq done-start (match-beginning 0))
4886 (setq done-sep-start (match-beginning 1)) 4910 (setq done-sep-start (match-beginning 1))
@@ -5264,7 +5288,8 @@ Overrides `diary-goto-entry'."
5264 (when (eq major-mode 'todo-mode) 5288 (when (eq major-mode 'todo-mode)
5265 (let ((opoint (point))) 5289 (let ((opoint (point)))
5266 (re-search-backward (concat "^" (regexp-quote todo-category-beg) 5290 (re-search-backward (concat "^" (regexp-quote todo-category-beg)
5267 "\\(.*\\)\n") nil t) 5291 "\\(.*\\)\n")
5292 nil t)
5268 (todo-category-number (match-string 1)) 5293 (todo-category-number (match-string 1))
5269 (todo-category-select) 5294 (todo-category-select)
5270 (goto-char opoint)))))) 5295 (goto-char opoint))))))
@@ -5647,8 +5672,7 @@ already entered and those still available."
5647(defvar todo-edit-item--prompt "Press a key (so far `e'): ") 5672(defvar todo-edit-item--prompt "Press a key (so far `e'): ")
5648 5673
5649(defun todo-edit-item--next-key (params &optional arg) 5674(defun todo-edit-item--next-key (params &optional arg)
5650 (let* ((map (make-sparse-keymap)) 5675 (let* ((p->k (mapconcat (lambda (elt)
5651 (p->k (mapconcat (lambda (elt)
5652 (format "%s=>%s" 5676 (format "%s=>%s"
5653 (propertize (cdr elt) 'face 5677 (propertize (cdr elt) 'face
5654 'todo-key-prompt) 5678 'todo-key-prompt)
@@ -5736,14 +5760,14 @@ have been removed."
5736 todo-global-current-todo-file) 5760 todo-global-current-todo-file)
5737 (todo-absolute-file-name todo-default-todo-file))) 5761 (todo-absolute-file-name todo-default-todo-file)))
5738 (files (or (unless archive 5762 (files (or (unless archive
5739 (mapcar 'todo-absolute-file-name 5763 (mapcar #'todo-absolute-file-name
5740 todo-category-completions-files)) 5764 todo-category-completions-files))
5741 (list curfile))) 5765 (list curfile)))
5742 listall listf) 5766 listall listf)
5743 ;; If file was just added, it has no category completions. 5767 ;; If file was just added, it has no category completions.
5744 (unless (zerop (buffer-size (find-buffer-visiting curfile))) 5768 (unless (zerop (buffer-size (find-buffer-visiting curfile)))
5745 (unless (member curfile todo-archives) 5769 (unless (member curfile todo-archives)
5746 (add-to-list 'files curfile)) 5770 (cl-pushnew curfile files :test #'equal))
5747 (dolist (f files listall) 5771 (dolist (f files listall)
5748 (with-current-buffer (find-file-noselect f 'nowarn) 5772 (with-current-buffer (find-file-noselect f 'nowarn)
5749 (if archive 5773 (if archive
@@ -5783,7 +5807,7 @@ return the absolute truename of a todo archive file. With non-nil
5783MUSTMATCH the name of an existing file must be chosen; 5807MUSTMATCH the name of an existing file must be chosen;
5784otherwise, a new file name is allowed." 5808otherwise, a new file name is allowed."
5785 (let* ((completion-ignore-case todo-completion-ignore-case) 5809 (let* ((completion-ignore-case todo-completion-ignore-case)
5786 (files (mapcar 'todo-short-file-name 5810 (files (mapcar #'todo-short-file-name
5787 ;; (funcall todo-files-function archive))) 5811 ;; (funcall todo-files-function archive)))
5788 (if archive todo-archives todo-files))) 5812 (if archive todo-archives todo-files)))
5789 (file (completing-read prompt files nil mustmatch nil nil 5813 (file (completing-read prompt files nil mustmatch nil nil
@@ -5832,7 +5856,8 @@ categories from `todo-category-completions-files'."
5832 (todo-read-file-name (concat "Choose a" (if archive 5856 (todo-read-file-name (concat "Choose a" (if archive
5833 "n archive" 5857 "n archive"
5834 " todo") 5858 " todo")
5835 " file: ") archive t))) 5859 " file: ")
5860 archive t)))
5836 (completions (unless file0 (todo-category-completions archive))) 5861 (completions (unless file0 (todo-category-completions archive)))
5837 (categories (cond (file0 5862 (categories (cond (file0
5838 (with-current-buffer 5863 (with-current-buffer
@@ -5873,7 +5898,7 @@ categories from `todo-category-completions-files'."
5873 (if (atom catfil) 5898 (if (atom catfil)
5874 catfil 5899 catfil
5875 (todo-absolute-file-name 5900 (todo-absolute-file-name
5876 (let ((files (mapcar 'todo-short-file-name catfil))) 5901 (let ((files (mapcar #'todo-short-file-name catfil)))
5877 (completing-read (format str cat) files))))))) 5902 (completing-read (format str cat) files)))))))
5878 ;; Default to the current file. 5903 ;; Default to the current file.
5879 (unless file0 (setq file0 todo-current-todo-file)) 5904 (unless file0 (setq file0 todo-current-todo-file))
@@ -5907,7 +5932,7 @@ categories from `todo-category-completions-files'."
5907 "Prompt for new NAME for TYPE until it is valid, then return it. 5932 "Prompt for new NAME for TYPE until it is valid, then return it.
5908TYPE can be either of the symbols `file' or `category'." 5933TYPE can be either of the symbols `file' or `category'."
5909 (let ((categories todo-categories) 5934 (let ((categories todo-categories)
5910 (files (mapcar 'todo-short-file-name todo-files)) 5935 (files (mapcar #'todo-short-file-name todo-files))
5911 prompt) 5936 prompt)
5912 (while 5937 (while
5913 (and 5938 (and
@@ -5981,8 +6006,8 @@ number of the last the day of the month."
5981 (setq monthname (completing-read 6006 (setq monthname (completing-read
5982 "Month name (RET for current month, * for any month): " 6007 "Month name (RET for current month, * for any month): "
5983 mlist nil t nil nil 6008 mlist nil t nil nil
5984 (calendar-month-name (calendar-extract-month 6009 (calendar-month-name
5985 (calendar-current-date)) t)) 6010 (calendar-extract-month (calendar-current-date)) t))
5986 month (1+ (- (length mlist) 6011 month (1+ (- (length mlist)
5987 (length (or (member monthname mlist) 6012 (length (or (member monthname mlist)
5988 (member monthname mablist)))))) 6013 (member monthname mablist))))))
@@ -6023,7 +6048,7 @@ number of the last the day of the month."
6023 (if (memq 'month calendar-date-display-form) 6048 (if (memq 'month calendar-date-display-form)
6024 month 6049 month
6025 monthname))) 6050 monthname)))
6026 (mapconcat 'eval calendar-date-display-form "")))) 6051 (mapconcat #'eval calendar-date-display-form ""))))
6027 6052
6028(defun todo-read-dayname () 6053(defun todo-read-dayname ()
6029 "Choose name of a day of the week with completion and return it." 6054 "Choose name of a day of the week with completion and return it."
@@ -6088,8 +6113,8 @@ the empty string (i.e., no time string)."
6088 "The :set function for user option `todo-show-current-file'." 6113 "The :set function for user option `todo-show-current-file'."
6089 (custom-set-default symbol value) 6114 (custom-set-default symbol value)
6090 (if value 6115 (if value
6091 (add-hook 'pre-command-hook 'todo-show-current-file nil t) 6116 (add-hook 'pre-command-hook #'todo-show-current-file nil t)
6092 (remove-hook 'pre-command-hook 'todo-show-current-file t))) 6117 (remove-hook 'pre-command-hook #'todo-show-current-file t)))
6093 6118
6094(defun todo-reset-prefix (symbol value) 6119(defun todo-reset-prefix (symbol value)
6095 "The :set function for `todo-prefix' and `todo-number-prefix'." 6120 "The :set function for `todo-prefix' and `todo-number-prefix'."
@@ -6228,6 +6253,8 @@ the empty string (i.e., no time string)."
6228 6253
6229(defun todo-reevaluate-filelist-defcustoms () 6254(defun todo-reevaluate-filelist-defcustoms ()
6230 "Reevaluate defcustoms that provide choice list of todo files." 6255 "Reevaluate defcustoms that provide choice list of todo files."
6256 ;; FIXME: This is hideous! I don't know enough about Custom to
6257 ;; offer something better, but please ask on emacs-devel!
6231 (custom-set-default 'todo-default-todo-file 6258 (custom-set-default 'todo-default-todo-file
6232 (symbol-value 'todo-default-todo-file)) 6259 (symbol-value 'todo-default-todo-file))
6233 (todo-reevaluate-default-file-defcustom) 6260 (todo-reevaluate-default-file-defcustom)
@@ -6242,15 +6269,15 @@ the empty string (i.e., no time string)."
6242Called after adding or deleting a todo file. If the value of 6269Called after adding or deleting a todo file. If the value of
6243`todo-default-todo-file' before calling this function was 6270`todo-default-todo-file' before calling this function was
6244associated with an existing file, keep that value." 6271associated with an existing file, keep that value."
6272 ;; FIXME: This is hideous! I don't know enough about Custom to
6273 ;; offer something better, but please ask on emacs-devel!
6245 ;; (let ((curval todo-default-todo-file)) 6274 ;; (let ((curval todo-default-todo-file))
6246 (eval 6275 (eval
6247 (defcustom todo-default-todo-file (todo-short-file-name 6276 (defcustom todo-default-todo-file (todo-short-file-name
6248 (car (funcall todo-files-function))) 6277 (car (funcall todo-files-function)))
6249 "Todo file visited by first session invocation of `todo-show'." 6278 "Todo file visited by first session invocation of `todo-show'."
6250 :type (when todo-files 6279 :type (when todo-files
6251 `(radio ,@(mapcar (lambda (f) (list 'const f)) 6280 `(radio ,@(todo--files-type-list)))
6252 (mapcar 'todo-short-file-name
6253 (funcall todo-files-function)))))
6254 :group 'todo)) 6281 :group 'todo))
6255 ;; (when (and curval (file-exists-p (todo-absolute-file-name curval))) 6282 ;; (when (and curval (file-exists-p (todo-absolute-file-name curval)))
6256 ;; (custom-set-default 'todo-default-todo-file curval) 6283 ;; (custom-set-default 'todo-default-todo-file curval)
@@ -6261,21 +6288,21 @@ associated with an existing file, keep that value."
6261(defun todo-reevaluate-category-completions-files-defcustom () 6288(defun todo-reevaluate-category-completions-files-defcustom ()
6262 "Reevaluate defcustom of `todo-category-completions-files'. 6289 "Reevaluate defcustom of `todo-category-completions-files'.
6263Called after adding or deleting a todo file." 6290Called after adding or deleting a todo file."
6291 ;; FIXME: This is hideous! I don't know enough about Custom to
6292 ;; offer something better, but please ask on emacs-devel!
6264 (eval (defcustom todo-category-completions-files nil 6293 (eval (defcustom todo-category-completions-files nil
6265 "List of files for building `todo-read-category' completions." 6294 "List of files for building `todo-read-category' completions."
6266 :type `(set ,@(mapcar (lambda (f) (list 'const f)) 6295 :type `(set ,@(todo--files-type-list))
6267 (mapcar 'todo-short-file-name
6268 (funcall todo-files-function))))
6269 :group 'todo))) 6296 :group 'todo)))
6270 6297
6271(defun todo-reevaluate-filter-files-defcustom () 6298(defun todo-reevaluate-filter-files-defcustom ()
6272 "Reevaluate defcustom of `todo-filter-files'. 6299 "Reevaluate defcustom of `todo-filter-files'.
6273Called after adding or deleting a todo file." 6300Called after adding or deleting a todo file."
6301 ;; FIXME: This is hideous! I don't know enough about Custom to
6302 ;; offer something better, but please ask on emacs-devel!
6274 (eval (defcustom todo-filter-files nil 6303 (eval (defcustom todo-filter-files nil
6275 "List of files for multifile item filtering." 6304 "List of files for multifile item filtering."
6276 :type `(set ,@(mapcar (lambda (f) (list 'const f)) 6305 :type `(set ,@(todo--files-type-list))
6277 (mapcar 'todo-short-file-name
6278 (funcall todo-files-function))))
6279 :group 'todo))) 6306 :group 'todo)))
6280 6307
6281;; ----------------------------------------------------------------------------- 6308;; -----------------------------------------------------------------------------
@@ -6292,7 +6319,8 @@ Called after adding or deleting a todo file."
6292(defun todo-diary-nonmarking-matcher (lim) 6319(defun todo-diary-nonmarking-matcher (lim)
6293 "Search for diary nonmarking symbol within LIM for font-locking." 6320 "Search for diary nonmarking symbol within LIM for font-locking."
6294 (re-search-forward (concat "^\\(?1:" (regexp-quote diary-nonmarking-symbol) 6321 (re-search-forward (concat "^\\(?1:" (regexp-quote diary-nonmarking-symbol)
6295 "\\)" todo-date-pattern) lim t)) 6322 "\\)" todo-date-pattern)
6323 lim t))
6296 6324
6297(defun todo-date-string-matcher (lim) 6325(defun todo-date-string-matcher (lim)
6298 "Search for todo item date string within LIM for font-locking." 6326 "Search for todo item date string within LIM for font-locking."
@@ -6302,14 +6330,16 @@ Called after adding or deleting a todo file."
6302(defun todo-time-string-matcher (lim) 6330(defun todo-time-string-matcher (lim)
6303 "Search for todo item time string within LIM for font-locking." 6331 "Search for todo item time string within LIM for font-locking."
6304 (re-search-forward (concat todo-date-string-start todo-date-pattern 6332 (re-search-forward (concat todo-date-string-start todo-date-pattern
6305 " \\(?1:" diary-time-regexp "\\)") lim t)) 6333 " \\(?1:" diary-time-regexp "\\)")
6334 lim t))
6306 6335
6307(defun todo-diary-expired-matcher (lim) 6336(defun todo-diary-expired-matcher (lim)
6308 "Search for expired diary item date within LIM for font-locking." 6337 "Search for expired diary item date within LIM for font-locking."
6309 (when (re-search-forward (concat "^\\(?:" 6338 (when (re-search-forward (concat "^\\(?:"
6310 (regexp-quote diary-nonmarking-symbol) 6339 (regexp-quote diary-nonmarking-symbol)
6311 "\\)?\\(?1:" todo-date-pattern "\\) \\(?2:" 6340 "\\)?\\(?1:" todo-date-pattern "\\) \\(?2:"
6312 diary-time-regexp "\\)?") lim t) 6341 diary-time-regexp "\\)?")
6342 lim t)
6313 (let* ((date (match-string-no-properties 1)) 6343 (let* ((date (match-string-no-properties 1))
6314 (time (match-string-no-properties 2)) 6344 (time (match-string-no-properties 2))
6315 ;; Function days-between requires a non-empty time string. 6345 ;; Function days-between requires a non-empty time string.
@@ -6464,8 +6494,6 @@ Filtered Items mode following todo (not done) items."
6464 6494
6465(defvar todo-mode-map 6495(defvar todo-mode-map
6466 (let ((map (make-keymap))) 6496 (let ((map (make-keymap)))
6467 ;; Don't suppress digit keys, so they can supply prefix arguments.
6468 (suppress-keymap map)
6469 (dolist (kb todo-key-bindings-t) 6497 (dolist (kb todo-key-bindings-t)
6470 (define-key map (nth 0 kb) (nth 1 kb))) 6498 (define-key map (nth 0 kb) (nth 1 kb)))
6471 (dolist (kb todo-key-bindings-t+a+f) 6499 (dolist (kb todo-key-bindings-t+a+f)
@@ -6479,7 +6507,6 @@ Filtered Items mode following todo (not done) items."
6479 6507
6480(defvar todo-archive-mode-map 6508(defvar todo-archive-mode-map
6481 (let ((map (make-sparse-keymap))) 6509 (let ((map (make-sparse-keymap)))
6482 (suppress-keymap map)
6483 (dolist (kb todo-key-bindings-t+a+f) 6510 (dolist (kb todo-key-bindings-t+a+f)
6484 (define-key map (nth 0 kb) (nth 1 kb))) 6511 (define-key map (nth 0 kb) (nth 1 kb)))
6485 (dolist (kb todo-key-bindings-t+a) 6512 (dolist (kb todo-key-bindings-t+a)
@@ -6498,7 +6525,6 @@ Filtered Items mode following todo (not done) items."
6498 6525
6499(defvar todo-categories-mode-map 6526(defvar todo-categories-mode-map
6500 (let ((map (make-sparse-keymap))) 6527 (let ((map (make-sparse-keymap)))
6501 (suppress-keymap map)
6502 (define-key map "c" 'todo-sort-categories-alphabetically-or-numerically) 6528 (define-key map "c" 'todo-sort-categories-alphabetically-or-numerically)
6503 (define-key map "t" 'todo-sort-categories-by-todo) 6529 (define-key map "t" 'todo-sort-categories-by-todo)
6504 (define-key map "y" 'todo-sort-categories-by-diary) 6530 (define-key map "y" 'todo-sort-categories-by-diary)
@@ -6517,7 +6543,6 @@ Filtered Items mode following todo (not done) items."
6517 6543
6518(defvar todo-filtered-items-mode-map 6544(defvar todo-filtered-items-mode-map
6519 (let ((map (make-sparse-keymap))) 6545 (let ((map (make-sparse-keymap)))
6520 (suppress-keymap map)
6521 (dolist (kb todo-key-bindings-t+a+f) 6546 (dolist (kb todo-key-bindings-t+a+f)
6522 (define-key map (nth 0 kb) (nth 1 kb))) 6547 (define-key map (nth 0 kb) (nth 1 kb)))
6523 (dolist (kb todo-key-bindings-t+f) 6548 (dolist (kb todo-key-bindings-t+f)
@@ -6651,9 +6676,9 @@ Added to `window-configuration-change-hook' in Todo mode."
6651(defun todo-modes-set-1 () 6676(defun todo-modes-set-1 ()
6652 "Make some settings that apply to multiple Todo modes." 6677 "Make some settings that apply to multiple Todo modes."
6653 (setq-local font-lock-defaults '(todo-font-lock-keywords t)) 6678 (setq-local font-lock-defaults '(todo-font-lock-keywords t))
6654 (setq-local revert-buffer-function 'todo-revert-buffer) 6679 (setq-local revert-buffer-function #'todo-revert-buffer)
6655 (setq-local tab-width todo-indent-to-here) 6680 (setq-local tab-width todo-indent-to-here)
6656 (setq-local indent-line-function 'todo-indent) 6681 (setq-local indent-line-function #'todo-indent)
6657 (when todo-wrap-lines 6682 (when todo-wrap-lines
6658 (visual-line-mode) 6683 (visual-line-mode)
6659 (setq wrap-prefix (make-string todo-indent-to-here 32)))) 6684 (setq wrap-prefix (make-string todo-indent-to-here 32))))
@@ -6671,13 +6696,13 @@ Added to `window-configuration-change-hook' in Todo mode."
6671 (setq buffer-read-only t) 6696 (setq buffer-read-only t)
6672 (setq-local todo--item-headers-hidden nil) 6697 (setq-local todo--item-headers-hidden nil)
6673 (setq-local desktop-save-buffer 'todo-desktop-save-buffer) 6698 (setq-local desktop-save-buffer 'todo-desktop-save-buffer)
6674 (setq-local hl-line-range-function 'todo-hl-line-range)) 6699 (setq-local hl-line-range-function #'todo-hl-line-range))
6675 6700
6676(defun todo-modes-set-3 () 6701(defun todo-modes-set-3 ()
6677 "Make some settings that apply to multiple Todo modes." 6702 "Make some settings that apply to multiple Todo modes."
6678 (setq-local todo-categories (todo-set-categories)) 6703 (setq-local todo-categories (todo-set-categories))
6679 (setq-local todo-category-number 1) 6704 (setq-local todo-category-number 1)
6680 ;; (add-hook 'find-file-hook 'todo-display-as-todo-file nil t) 6705 ;; (add-hook 'find-file-hook #'todo-display-as-todo-file nil t)
6681 ) 6706 )
6682 6707
6683(put 'todo-mode 'mode-class 'special) 6708(put 'todo-mode 'mode-class 'special)
@@ -6700,13 +6725,13 @@ Added to `window-configuration-change-hook' in Todo mode."
6700 (setq-local todo-current-todo-file (file-truename (buffer-file-name)))) 6725 (setq-local todo-current-todo-file (file-truename (buffer-file-name))))
6701 (setq-local todo-show-done-only nil) 6726 (setq-local todo-show-done-only nil)
6702 (setq-local todo-categories-with-marks nil) 6727 (setq-local todo-categories-with-marks nil)
6703 ;; (add-hook 'find-file-hook 'todo-add-to-buffer-list nil t) 6728 ;; (add-hook 'find-file-hook #'todo-add-to-buffer-list nil t)
6704 (add-hook 'post-command-hook 'todo-update-buffer-list nil t) 6729 (add-hook 'post-command-hook #'todo-update-buffer-list nil t)
6705 (when todo-show-current-file 6730 (when todo-show-current-file
6706 (add-hook 'pre-command-hook 'todo-show-current-file nil t)) 6731 (add-hook 'pre-command-hook #'todo-show-current-file nil t))
6707 (add-hook 'window-configuration-change-hook 6732 (add-hook 'window-configuration-change-hook
6708 'todo-reset-and-enable-done-separator nil t) 6733 #'todo-reset-and-enable-done-separator nil t)
6709 (add-hook 'kill-buffer-hook 'todo-reset-global-current-todo-file nil t))) 6734 (add-hook 'kill-buffer-hook #'todo-reset-global-current-todo-file nil t)))
6710 6735
6711(put 'todo-archive-mode 'mode-class 'special) 6736(put 'todo-archive-mode 'mode-class 'special)
6712 6737
diff --git a/lisp/cus-start.el b/lisp/cus-start.el
index 744fe7f69ee..c28b8a147fc 100644
--- a/lisp/cus-start.el
+++ b/lisp/cus-start.el
@@ -584,6 +584,38 @@ since it could result in memory overflow and make Emacs crash."
584 (const :tag "Grow only" :value grow-only)) 584 (const :tag "Grow only" :value grow-only))
585 "25.1") 585 "25.1")
586 (display-raw-bytes-as-hex display boolean "26.1") 586 (display-raw-bytes-as-hex display boolean "26.1")
587 (display-line-numbers display-line-numbers
588 (choice
589 (const :tag "Off (nil)" :value nil)
590 (const :tag "Absolute line numbers"
591 :value t)
592 (const :tag "Relative line numbers"
593 :value relative)
594 (const :tag "Visually relative line numbers"
595 :value visual))
596 "26.1")
597 (display-line-numbers-width display-line-numbers
598 (choice
599 (const :tag "Dynamically computed"
600 :value nil)
601 (integer :menu-tag "Fixed number of columns"
602 :value 2
603 :format "%v"))
604 "26.1")
605 (display-line-numbers-current-absolute display-line-numbers
606 (choice
607 (const :tag "Display actual number of current line"
608 :value t)
609 (const :tag "Display zero as number of current line"
610 :value nil))
611 "26.1")
612 (display-line-numbers-widen display-line-numbers
613 (choice
614 (const :tag "Disregard narrowing when calculating line numbers"
615 :value t)
616 (const :tag "Count lines from beginning of narrowed region"
617 :value nil))
618 "26.1")
587 ;; xfaces.c 619 ;; xfaces.c
588 (scalable-fonts-allowed display boolean "22.1") 620 (scalable-fonts-allowed display boolean "22.1")
589 ;; xfns.c 621 ;; xfns.c
diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index 095ce8ba89c..17dae6085df 100644
--- a/lisp/dired-aux.el
+++ b/lisp/dired-aux.el
@@ -1623,10 +1623,14 @@ Special value `always' suppresses confirmation."
1623 (setq default-directory to 1623 (setq default-directory to
1624 dired-directory (expand-file-name;; this is correct 1624 dired-directory (expand-file-name;; this is correct
1625 ;; with and without wildcards 1625 ;; with and without wildcards
1626 (file-name-nondirectory dired-directory) 1626 (file-name-nondirectory (if (stringp dired-directory)
1627 dired-directory
1628 (car dired-directory)))
1627 to)) 1629 to))
1628 (let ((new-name (file-name-nondirectory 1630 (let ((new-name (file-name-nondirectory
1629 (directory-file-name dired-directory)))) 1631 (directory-file-name (if (stringp dired-directory)
1632 dired-directory
1633 (car dired-directory))))))
1630 ;; try to rename buffer, but just leave old name if new 1634 ;; try to rename buffer, but just leave old name if new
1631 ;; name would already exist (don't try appending "<%d>") 1635 ;; name would already exist (don't try appending "<%d>")
1632 (or (get-buffer new-name) 1636 (or (get-buffer new-name)
diff --git a/lisp/dired-x.el b/lisp/dired-x.el
index 7ceb672bf2f..915550991d0 100644
--- a/lisp/dired-x.el
+++ b/lisp/dired-x.el
@@ -546,7 +546,9 @@ Should never be used as marker by the user or other packages.")
546 (interactive) 546 (interactive)
547 (let ((dired-omit-mode nil)) (revert-buffer)) ;; Show omitted files 547 (let ((dired-omit-mode nil)) (revert-buffer)) ;; Show omitted files
548 (dired-mark-unmarked-files (dired-omit-regexp) nil nil dired-omit-localp 548 (dired-mark-unmarked-files (dired-omit-regexp) nil nil dired-omit-localp
549 (dired-omit-case-fold-p dired-directory))) 549 (dired-omit-case-fold-p (if (stringp dired-directory)
550 dired-directory
551 (car dired-directory)))))
550 552
551(defcustom dired-omit-extensions 553(defcustom dired-omit-extensions
552 (append completion-ignored-extensions 554 (append completion-ignored-extensions
@@ -591,7 +593,9 @@ This functions works by temporarily binding `dired-marker-char' to
591 (let ((dired-marker-char dired-omit-marker-char)) 593 (let ((dired-marker-char dired-omit-marker-char))
592 (when dired-omit-verbose (message "Omitting...")) 594 (when dired-omit-verbose (message "Omitting..."))
593 (if (dired-mark-unmarked-files omit-re nil nil dired-omit-localp 595 (if (dired-mark-unmarked-files omit-re nil nil dired-omit-localp
594 (dired-omit-case-fold-p dired-directory)) 596 (dired-omit-case-fold-p (if (stringp dired-directory)
597 dired-directory
598 (car dired-directory))))
595 (progn 599 (progn
596 (setq count (dired-do-kill-lines 600 (setq count (dired-do-kill-lines
597 nil 601 nil
diff --git a/lisp/dired.el b/lisp/dired.el
index 0c1f3e4af64..9d500a9f52d 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -785,7 +785,7 @@ Type \\[describe-mode] after entering Dired for more info.
785If DIRNAME is already in a Dired buffer, that buffer is used without refresh." 785If DIRNAME is already in a Dired buffer, that buffer is used without refresh."
786 ;; Cannot use (interactive "D") because of wildcards. 786 ;; Cannot use (interactive "D") because of wildcards.
787 (interactive (dired-read-dir-and-switches "")) 787 (interactive (dired-read-dir-and-switches ""))
788 (switch-to-buffer (dired-noselect dirname switches))) 788 (pop-to-buffer-same-window (dired-noselect dirname switches)))
789 789
790;;;###autoload (define-key ctl-x-4-map "d" 'dired-other-window) 790;;;###autoload (define-key ctl-x-4-map "d" 'dired-other-window)
791;;;###autoload 791;;;###autoload
@@ -872,13 +872,15 @@ periodically reverts at specified time intervals."
872 :version "23.2") 872 :version "23.2")
873 873
874(defun dired-internal-noselect (dir-or-list &optional switches mode) 874(defun dired-internal-noselect (dir-or-list &optional switches mode)
875 ;; If there is an existing dired buffer for DIRNAME, just leave 875 ;; If DIR-OR-LIST is a string and there is an existing dired buffer
876 ;; buffer as it is (don't even call dired-revert). 876 ;; for it, just leave buffer as it is (don't even call dired-revert).
877 ;; This saves time especially for deep trees or with ange-ftp. 877 ;; This saves time especially for deep trees or with ange-ftp.
878 ;; The user can type `g' easily, and it is more consistent with find-file. 878 ;; The user can type `g' easily, and it is more consistent with find-file.
879 ;; But if SWITCHES are given they are probably different from the 879 ;; But if SWITCHES are given they are probably different from the
880 ;; buffer's old value, so call dired-sort-other, which does 880 ;; buffer's old value, so call dired-sort-other, which does
881 ;; revert the buffer. 881 ;; revert the buffer.
882 ;; Revert the buffer if DIR-OR-LIST is a cons or `dired-directory'
883 ;; is a cons and DIR-OR-LIST is a string.
882 ;; A pity we can't possibly do "Directory has changed - refresh? " 884 ;; A pity we can't possibly do "Directory has changed - refresh? "
883 ;; like find-file does. 885 ;; like find-file does.
884 ;; Optional argument MODE is passed to dired-find-buffer-nocreate, 886 ;; Optional argument MODE is passed to dired-find-buffer-nocreate,
@@ -898,6 +900,11 @@ periodically reverts at specified time intervals."
898 (setq dired-directory dir-or-list) 900 (setq dired-directory dir-or-list)
899 ;; this calls dired-revert 901 ;; this calls dired-revert
900 (dired-sort-other switches)) 902 (dired-sort-other switches))
903 ;; Always revert when `dir-or-list' is a cons. Also revert
904 ;; if `dired-directory' is a cons but `dir-or-list' is not.
905 ((or (consp dir-or-list) (consp dired-directory))
906 (setq dired-directory dir-or-list)
907 (revert-buffer))
901 ;; Always revert regardless of whether it has changed or not. 908 ;; Always revert regardless of whether it has changed or not.
902 ((eq dired-auto-revert-buffer t) 909 ((eq dired-auto-revert-buffer t)
903 (revert-buffer)) 910 (revert-buffer))
diff --git a/lisp/display-line-numbers.el b/lisp/display-line-numbers.el
new file mode 100644
index 00000000000..a99474547bf
--- /dev/null
+++ b/lisp/display-line-numbers.el
@@ -0,0 +1,106 @@
1;;; display-line-numbers.el --- interface for display-line-numbers -*- lexical-binding: t -*-
2
3;; Copyright (C) 2017 Free Software Foundation, Inc.
4
5;; Maintainer: emacs-devel@gnu.org
6;; Keywords: convenience
7
8;; This file is part of GNU Emacs.
9
10;; GNU Emacs is free software: you can redistribute it and/or modify
11;; it under the terms of the GNU General Public License as published by
12;; the Free Software Foundation, either version 3 of the License, or
13;; (at your option) any later version.
14
15;; GNU Emacs is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;; GNU General Public License for more details.
19
20;; You should have received a copy of the GNU General Public License
21;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
22
23;;; Commentary:
24
25;; Provides a minor mode interface for `display-line-numbers'.
26;;
27;; Toggle display of line numbers with M-x display-line-numbers-mode.
28;; To enable line numbering in all buffers, use M-x
29;; global-display-line-numbers-mode. To change the default type of
30;; line numbers displayed, customize display-line-numbers-type.
31
32;; NOTE: Customization variables for `display-line-numbers' itself are
33;; defined in cus-start.el.
34
35;;; Code:
36
37(defgroup display-line-numbers nil
38 "Display line numbers in the buffer."
39 :group 'display)
40
41;;;###autoload
42(defcustom display-line-numbers-type t
43 "The default type of line numbers to use in `display-line-numbers-mode'.
44See `display-line-numbers' for value options."
45 :group 'display-line-numbers
46 :type '(choice (const :tag "Relative line numbers" relative)
47 (const :tag "Relative visual line numbers" visual)
48 (other :tag "Absolute line numbers" t))
49 :version "26.1")
50
51(defcustom display-line-numbers-grow-only nil
52 "If non-nil, do not shrink line number width."
53 :group 'display-line-numbers
54 :type 'boolean
55 :version "26.1")
56
57(defcustom display-line-numbers-width-start nil
58 "If non-nil, count number of lines to use for line number width.
59When `display-line-numbers-mode' is turned on,
60`display-line-numbers-width' is set to the minimum width necessary
61to display all line numbers in the buffer."
62 :group 'display-line-numbers
63 :type 'boolean
64 :version "26.1")
65
66(defun display-line-numbers-update-width ()
67 "Prevent the line number width from shrinking."
68 (let ((width (line-number-display-width)))
69 (when (> width (or display-line-numbers-width 1))
70 (setq display-line-numbers-width width))))
71
72;;;###autoload
73(define-minor-mode display-line-numbers-mode
74 "Toggle display of line numbers in the buffer.
75This uses `display-line-numbers' internally.
76
77To change the type of line numbers displayed by default,
78customize `display-line-numbers-type'. To change the type while
79the mode is on, set `display-line-numbers' directly."
80 :lighter nil
81 (if display-line-numbers-mode
82 (progn
83 (when display-line-numbers-width-start
84 (setq display-line-numbers-width
85 (length (number-to-string
86 (count-lines (point-min) (point-max))))))
87 (when display-line-numbers-grow-only
88 (add-hook 'pre-command-hook #'display-line-numbers-update-width nil t))
89 (setq display-line-numbers display-line-numbers-type))
90 (remove-hook 'pre-command-hook #'display-line-numbers-update-width t)
91 (setq display-line-numbers nil)))
92
93(defun display-line-numbers--turn-on ()
94 "Turn on `display-line-numbers-mode'."
95 (unless (or (minibufferp)
96 ;; taken from linum.el
97 (and (daemonp) (null (frame-parameter nil 'client))))
98 (display-line-numbers-mode)))
99
100;;;###autoload
101(define-globalized-minor-mode global-display-line-numbers-mode
102 display-line-numbers-mode display-line-numbers--turn-on)
103
104(provide 'display-line-numbers)
105
106;;; display-line-numbers.el ends here
diff --git a/lisp/electric.el b/lisp/electric.el
index 4c1d9039d9a..a71e79ff78a 100644
--- a/lisp/electric.el
+++ b/lisp/electric.el
@@ -469,56 +469,50 @@ This requotes when a quoting key is typed."
469 (and (not electric-quote-context-sensitive) 469 (and (not electric-quote-context-sensitive)
470 (eq last-command-event ?\`))) 470 (eq last-command-event ?\`)))
471 (not (run-hook-with-args-until-success 471 (not (run-hook-with-args-until-success
472 'electric-quote-inhibit-functions))) 472 'electric-quote-inhibit-functions))
473 (let ((start 473 (if (derived-mode-p 'text-mode)
474 (if (and comment-start comment-use-syntax) 474 electric-quote-paragraph
475 (when (or electric-quote-comment electric-quote-string) 475 (and comment-start comment-use-syntax
476 (let* ((syntax (syntax-ppss)) 476 (or electric-quote-comment electric-quote-string)
477 (beg (nth 8 syntax))) 477 (let* ((syntax (syntax-ppss))
478 (and beg 478 (beg (nth 8 syntax)))
479 (or (and electric-quote-comment (nth 4 syntax)) 479 (and beg
480 (and electric-quote-string (nth 3 syntax))) 480 (or (and electric-quote-comment (nth 4 syntax))
481 ;; Do not requote a quote that starts or ends 481 (and electric-quote-string (nth 3 syntax)))
482 ;; a comment or string. 482 ;; Do not requote a quote that starts or ends
483 (eq beg (nth 8 (save-excursion 483 ;; a comment or string.
484 (syntax-ppss (1- (point))))))))) 484 (eq beg (nth 8 (save-excursion
485 (and electric-quote-paragraph 485 (syntax-ppss (1- (point)))))))))))
486 (derived-mode-p 'text-mode) 486 (pcase electric-quote-chars
487 ;; FIXME: Why is the next form there? It’s never 487 (`(,q< ,q> ,q<< ,q>>)
488 ;; nil. 488 (save-excursion
489 (or (eq last-command-event ?\`) 489 (let ((backtick ?\`))
490 (save-excursion (backward-paragraph) (point))))))) 490 (if (or (eq last-command-event ?\`)
491 (pcase electric-quote-chars 491 (and electric-quote-context-sensitive
492 (`(,q< ,q> ,q<< ,q>>) 492 (save-excursion
493 (when start 493 (backward-char)
494 (save-excursion 494 (or (bobp) (bolp)
495 (let ((backtick ?\`)) 495 (memq (char-before) (list q< q<<))
496 (if (or (eq last-command-event ?\`) 496 (memq (char-syntax (char-before))
497 (and electric-quote-context-sensitive 497 '(?\s ?\())))
498 (save-excursion 498 (setq backtick ?\')))
499 (backward-char) 499 (cond ((search-backward (string q< backtick) (- (point) 2) t)
500 (or (bobp) (bolp) 500 (replace-match (string q<<))
501 (memq (char-before) (list q< q<<)) 501 (when (and electric-pair-mode
502 (memq (char-syntax (char-before)) 502 (eq (cdr-safe
503 '(?\s ?\()))) 503 (assq q< electric-pair-text-pairs))
504 (setq backtick ?\'))) 504 (char-after)))
505 (cond ((search-backward (string q< backtick) (- (point) 2) t) 505 (delete-char 1))
506 (replace-match (string q<<)) 506 (setq last-command-event q<<))
507 (when (and electric-pair-mode 507 ((search-backward (string backtick) (1- (point)) t)
508 (eq (cdr-safe 508 (replace-match (string q<))
509 (assq q< electric-pair-text-pairs)) 509 (setq last-command-event q<)))
510 (char-after))) 510 (cond ((search-backward (string q> ?') (- (point) 2) t)
511 (delete-char 1)) 511 (replace-match (string q>>))
512 (setq last-command-event q<<)) 512 (setq last-command-event q>>))
513 ((search-backward (string backtick) (1- (point)) t) 513 ((search-backward "'" (1- (point)) t)
514 (replace-match (string q<)) 514 (replace-match (string q>))
515 (setq last-command-event q<))) 515 (setq last-command-event q>))))))))))
516 (cond ((search-backward (string q> ?') (- (point) 2) t)
517 (replace-match (string q>>))
518 (setq last-command-event q>>))
519 ((search-backward "'" (1- (point)) t)
520 (replace-match (string q>))
521 (setq last-command-event q>))))))))))))
522 516
523(put 'electric-quote-post-self-insert-function 'priority 10) 517(put 'electric-quote-post-self-insert-function 'priority 10)
524 518
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index e5b9b47b1d0..fdd4276e4e7 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -1263,12 +1263,6 @@ when printing the error message."
1263 1263
1264(defun byte-compile-arglist-signature (arglist) 1264(defun byte-compile-arglist-signature (arglist)
1265 (cond 1265 (cond
1266 ;; New style byte-code arglist.
1267 ((integerp arglist)
1268 (cons (logand arglist 127) ;Mandatory.
1269 (if (zerop (logand arglist 128)) ;No &rest.
1270 (lsh arglist -8)))) ;Nonrest.
1271 ;; Old style byte-code, or interpreted function.
1272 ((listp arglist) 1266 ((listp arglist)
1273 (let ((args 0) 1267 (let ((args 0)
1274 opts 1268 opts
@@ -1289,6 +1283,19 @@ when printing the error message."
1289 ;; Unknown arglist. 1283 ;; Unknown arglist.
1290 (t '(0)))) 1284 (t '(0))))
1291 1285
1286(defun byte-compile--function-signature (f)
1287 ;; Similar to help-function-arglist, except that it returns the info
1288 ;; in a different format.
1289 (and (eq 'macro (car-safe f)) (setq f (cdr f)))
1290 ;; Advice wrappers have "catch all" args, so fetch the actual underlying
1291 ;; function to find the real arguments.
1292 (while (advice--p f) (setq f (advice--cdr f)))
1293 (if (eq (car-safe f) 'declared)
1294 (byte-compile-arglist-signature (nth 1 f))
1295 (condition-case nil
1296 (let ((sig (func-arity f)))
1297 (if (numberp (cdr sig)) sig (list (car sig))))
1298 (error '(0)))))
1292 1299
1293(defun byte-compile-arglist-signatures-congruent-p (old new) 1300(defun byte-compile-arglist-signatures-congruent-p (old new)
1294 (not (or 1301 (not (or
@@ -1330,19 +1337,7 @@ when printing the error message."
1330(defun byte-compile-callargs-warn (form) 1337(defun byte-compile-callargs-warn (form)
1331 (let* ((def (or (byte-compile-fdefinition (car form) nil) 1338 (let* ((def (or (byte-compile-fdefinition (car form) nil)
1332 (byte-compile-fdefinition (car form) t))) 1339 (byte-compile-fdefinition (car form) t)))
1333 (sig (if (and def (not (eq def t))) 1340 (sig (byte-compile--function-signature def))
1334 (progn
1335 (and (eq (car-safe def) 'macro)
1336 (eq (car-safe (cdr-safe def)) 'lambda)
1337 (setq def (cdr def)))
1338 (byte-compile-arglist-signature
1339 (if (memq (car-safe def) '(declared lambda))
1340 (nth 1 def)
1341 (if (byte-code-function-p def)
1342 (aref def 0)
1343 '(&rest def)))))
1344 (if (subrp (symbol-function (car form)))
1345 (subr-arity (symbol-function (car form))))))
1346 (ncall (length (cdr form)))) 1341 (ncall (length (cdr form))))
1347 ;; Check many or unevalled from subr-arity. 1342 ;; Check many or unevalled from subr-arity.
1348 (if (and (cdr-safe sig) 1343 (if (and (cdr-safe sig)
@@ -1461,15 +1456,7 @@ extra args."
1461 (and initial (symbolp initial) 1456 (and initial (symbolp initial)
1462 (setq old (byte-compile-fdefinition initial nil))) 1457 (setq old (byte-compile-fdefinition initial nil)))
1463 (when (and old (not (eq old t))) 1458 (when (and old (not (eq old t)))
1464 (and (eq 'macro (car-safe old)) 1459 (let ((sig1 (byte-compile--function-signature old))
1465 (eq 'lambda (car-safe (cdr-safe old)))
1466 (setq old (cdr old)))
1467 (let ((sig1 (byte-compile-arglist-signature
1468 (pcase old
1469 (`(lambda ,args . ,_) args)
1470 (`(closure ,_ ,args . ,_) args)
1471 ((pred byte-code-function-p) (aref old 0))
1472 (_ '(&rest def)))))
1473 (sig2 (byte-compile-arglist-signature arglist))) 1460 (sig2 (byte-compile-arglist-signature arglist)))
1474 (unless (byte-compile-arglist-signatures-congruent-p sig1 sig2) 1461 (unless (byte-compile-arglist-signatures-congruent-p sig1 sig2)
1475 (byte-compile-set-symbol-position name) 1462 (byte-compile-set-symbol-position name)
diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el
index c64376b940f..6a4ee47ac24 100644
--- a/lisp/emacs-lisp/cl-generic.el
+++ b/lisp/emacs-lisp/cl-generic.el
@@ -182,8 +182,7 @@ SPECIALIZERS-FUNCTION takes as first argument a tag value TAG
182 origname)) 182 origname))
183 (if generic 183 (if generic
184 (cl-assert (eq name (cl--generic-name generic))) 184 (cl-assert (eq name (cl--generic-name generic)))
185 (setf (cl--generic name) (setq generic (cl--generic-make name))) 185 (setf (cl--generic name) (setq generic (cl--generic-make name))))
186 (defalias name (cl--generic-make-function generic)))
187 generic)) 186 generic))
188 187
189;;;###autoload 188;;;###autoload
@@ -1210,5 +1209,18 @@ Used internally for the (major-mode MODE) context specializers."
1210 (progn (cl-assert (null modes)) mode) 1209 (progn (cl-assert (null modes)) mode)
1211 `(derived-mode ,mode . ,modes)))) 1210 `(derived-mode ,mode . ,modes))))
1212 1211
1212;;; Support for unloading.
1213
1214(cl-defmethod loadhist-unload-element ((x (head cl-defmethod)))
1215 (pcase-let*
1216 ((`(,name ,qualifiers . ,specializers) (cdr x))
1217 (generic (cl-generic-ensure-function name 'noerror)))
1218 (when generic
1219 (let* ((mt (cl--generic-method-table generic))
1220 (me (cl--generic-member-method specializers qualifiers mt)))
1221 (when me
1222 (setf (cl--generic-method-table generic) (delq (car me) mt)))))))
1223
1224
1213(provide 'cl-generic) 1225(provide 'cl-generic)
1214;;; cl-generic.el ends here 1226;;; cl-generic.el ends here
diff --git a/lisp/emacs-lisp/cl-lib.el b/lisp/emacs-lisp/cl-lib.el
index 936c852526c..6ac08d839b1 100644
--- a/lisp/emacs-lisp/cl-lib.el
+++ b/lisp/emacs-lisp/cl-lib.el
@@ -288,14 +288,6 @@ If true return the decimal value of digit CHAR in RADIX."
288 (let ((n (aref cl-digit-char-table char))) 288 (let ((n (aref cl-digit-char-table char)))
289 (and n (< n (or radix 10)) n))) 289 (and n (< n (or radix 10)) n)))
290 290
291(defun cl--random-time ()
292 (let* ((time (copy-sequence (current-time-string))) (i (length time)) (v 0))
293 (while (>= (cl-decf i) 0) (setq v (+ (* v 3) (aref time i))))
294 v))
295
296(defvar cl--random-state
297 (vector 'cl--random-state-tag -1 30 (cl--random-time)))
298
299(defconst cl-most-positive-float nil 291(defconst cl-most-positive-float nil
300 "The largest value that a Lisp float can hold. 292 "The largest value that a Lisp float can hold.
301If your system supports infinities, this is the largest finite value. 293If your system supports infinities, this is the largest finite value.
@@ -639,7 +631,7 @@ If ALIST is non-nil, the new pairs are prepended to it."
639 (require 'cl-seq)) 631 (require 'cl-seq))
640 632
641(defun cl--old-struct-type-of (orig-fun object) 633(defun cl--old-struct-type-of (orig-fun object)
642 (or (and (vectorp object) 634 (or (and (vectorp object) (> (length object) 0)
643 (let ((tag (aref object 0))) 635 (let ((tag (aref object 0)))
644 (when (and (symbolp tag) 636 (when (and (symbolp tag)
645 (string-prefix-p "cl-struct-" (symbol-name tag))) 637 (string-prefix-p "cl-struct-" (symbol-name tag)))
diff --git a/lisp/emacs-lisp/edebug.el b/lisp/emacs-lisp/edebug.el
index 65e30f86778..1494ed1d9c3 100644
--- a/lisp/emacs-lisp/edebug.el
+++ b/lisp/emacs-lisp/edebug.el
@@ -906,7 +906,7 @@ circular objects. Let `read' read everything else."
906 ;; with the object itself, wherever it occurs. 906 ;; with the object itself, wherever it occurs.
907 (forward-char 1) 907 (forward-char 1)
908 (let ((obj (edebug-read-storing-offsets stream))) 908 (let ((obj (edebug-read-storing-offsets stream)))
909 (substitute-object-in-subtree obj placeholder) 909 (lread--substitute-object-in-subtree obj placeholder t)
910 (throw 'return (setf (cdr elem) obj))))) 910 (throw 'return (setf (cdr elem) obj)))))
911 ((eq ?# (following-char)) 911 ((eq ?# (following-char))
912 ;; #n# returns a previously read object. 912 ;; #n# returns a previously read object.
diff --git a/lisp/emacs-lisp/eldoc.el b/lisp/emacs-lisp/eldoc.el
index a05bd7cc4d4..bca40ab87da 100644
--- a/lisp/emacs-lisp/eldoc.el
+++ b/lisp/emacs-lisp/eldoc.el
@@ -160,6 +160,10 @@ This is used to determine if `eldoc-idle-delay' is changed by the user.")
160It should receive the same arguments as `message'.") 160It should receive the same arguments as `message'.")
161 161
162(defun eldoc-edit-message-commands () 162(defun eldoc-edit-message-commands ()
163 "Return an obarray containing common editing commands.
164
165When `eldoc-print-after-edit' is non-nil, ElDoc messages are only
166printed after commands contained in this obarray."
163 (let ((cmds (make-vector 31 0)) 167 (let ((cmds (make-vector 31 0))
164 (re (regexp-opt '("delete" "insert" "edit" "electric" "newline")))) 168 (re (regexp-opt '("delete" "insert" "edit" "electric" "newline"))))
165 (mapatoms (lambda (s) 169 (mapatoms (lambda (s)
@@ -211,16 +215,21 @@ expression point is on."
211 215
212;;;###autoload 216;;;###autoload
213(defun turn-on-eldoc-mode () 217(defun turn-on-eldoc-mode ()
214 "Turn on `eldoc-mode' if the buffer has eldoc support enabled. 218 "Turn on `eldoc-mode' if the buffer has ElDoc support enabled.
215See `eldoc-documentation-function' for more detail." 219See `eldoc-documentation-function' for more detail."
216 (when (eldoc--supported-p) 220 (when (eldoc--supported-p)
217 (eldoc-mode 1))) 221 (eldoc-mode 1)))
218 222
219(defun eldoc--supported-p () 223(defun eldoc--supported-p ()
224 "Non-nil if an ElDoc function is set for this buffer."
220 (not (memq eldoc-documentation-function '(nil ignore)))) 225 (not (memq eldoc-documentation-function '(nil ignore))))
221 226
222 227
223(defun eldoc-schedule-timer () 228(defun eldoc-schedule-timer ()
229 "Ensure `eldoc-timer' is running.
230
231If the user has changed `eldoc-idle-delay', update the timer to
232reflect the change."
224 (or (and eldoc-timer 233 (or (and eldoc-timer
225 (memq eldoc-timer timer-idle-list)) ;FIXME: Why? 234 (memq eldoc-timer timer-idle-list)) ;FIXME: Why?
226 (setq eldoc-timer 235 (setq eldoc-timer
@@ -229,8 +238,7 @@ See `eldoc-documentation-function' for more detail."
229 (lambda () 238 (lambda ()
230 (when (or eldoc-mode 239 (when (or eldoc-mode
231 (and global-eldoc-mode 240 (and global-eldoc-mode
232 (not (memq eldoc-documentation-function 241 (eldoc--supported-p)))
233 '(nil ignore)))))
234 (eldoc-print-current-symbol-info)))))) 242 (eldoc-print-current-symbol-info))))))
235 243
236 ;; If user has changed the idle delay, update the timer. 244 ;; If user has changed the idle delay, update the timer.
@@ -268,16 +276,19 @@ Otherwise work like `message'."
268 (force-mode-line-update))) 276 (force-mode-line-update)))
269 (apply 'message format-string args))) 277 (apply 'message format-string args)))
270 278
271(defun eldoc-message (&rest args) 279(defun eldoc-message (&optional format-string &rest args)
280 "Display FORMAT-STRING formatted with ARGS as an ElDoc message.
281
282Store the message (if any) in `eldoc-last-message', and return it."
272 (let ((omessage eldoc-last-message)) 283 (let ((omessage eldoc-last-message))
273 (setq eldoc-last-message 284 (setq eldoc-last-message
274 (cond ((eq (car args) eldoc-last-message) eldoc-last-message) 285 (cond ((eq format-string eldoc-last-message) eldoc-last-message)
275 ((null (car args)) nil) 286 ((null format-string) nil)
276 ;; If only one arg, no formatting to do, so put it in 287 ;; If only one arg, no formatting to do, so put it in
277 ;; eldoc-last-message so eq test above might succeed on 288 ;; eldoc-last-message so eq test above might succeed on
278 ;; subsequent calls. 289 ;; subsequent calls.
279 ((null (cdr args)) (car args)) 290 ((null args) format-string)
280 (t (apply #'format-message args)))) 291 (t (apply #'format-message format-string args))))
281 ;; In emacs 19.29 and later, and XEmacs 19.13 and later, all messages 292 ;; In emacs 19.29 and later, and XEmacs 19.13 and later, all messages
282 ;; are recorded in a log. Do not put eldoc messages in that log since 293 ;; are recorded in a log. Do not put eldoc messages in that log since
283 ;; they are Legion. 294 ;; they are Legion.
@@ -289,6 +300,7 @@ Otherwise work like `message'."
289 eldoc-last-message) 300 eldoc-last-message)
290 301
291(defun eldoc--message-command-p (command) 302(defun eldoc--message-command-p (command)
303 "Return non-nil if COMMAND is in `eldoc-message-commands'."
292 (and (symbolp command) 304 (and (symbolp command)
293 (intern-soft (symbol-name command) eldoc-message-commands))) 305 (intern-soft (symbol-name command) eldoc-message-commands)))
294 306
@@ -299,6 +311,7 @@ Otherwise work like `message'."
299;; before the next command executes, which does away with the flicker. 311;; before the next command executes, which does away with the flicker.
300;; This doesn't seem to be required for Emacs 19.28 and earlier. 312;; This doesn't seem to be required for Emacs 19.28 and earlier.
301(defun eldoc-pre-command-refresh-echo-area () 313(defun eldoc-pre-command-refresh-echo-area ()
314 "Reprint `eldoc-last-message' in the echo area."
302 (and eldoc-last-message 315 (and eldoc-last-message
303 (not (minibufferp)) ;We don't use the echo area when in minibuffer. 316 (not (minibufferp)) ;We don't use the echo area when in minibuffer.
304 (if (and (eldoc-display-message-no-interference-p) 317 (if (and (eldoc-display-message-no-interference-p)
@@ -310,6 +323,7 @@ Otherwise work like `message'."
310 323
311;; Decide whether now is a good time to display a message. 324;; Decide whether now is a good time to display a message.
312(defun eldoc-display-message-p () 325(defun eldoc-display-message-p ()
326 "Return non-nil when it is appropriate to display an ElDoc message."
313 (and (eldoc-display-message-no-interference-p) 327 (and (eldoc-display-message-no-interference-p)
314 ;; If this-command is non-nil while running via an idle 328 ;; If this-command is non-nil while running via an idle
315 ;; timer, we're still in the middle of executing a command, 329 ;; timer, we're still in the middle of executing a command,
@@ -322,6 +336,7 @@ Otherwise work like `message'."
322;; Check various conditions about the current environment that might make 336;; Check various conditions about the current environment that might make
323;; it undesirable to print eldoc messages right this instant. 337;; it undesirable to print eldoc messages right this instant.
324(defun eldoc-display-message-no-interference-p () 338(defun eldoc-display-message-no-interference-p ()
339 "Return nil if displaying a message would cause interference."
325 (not (or executing-kbd-macro (bound-and-true-p edebug-active)))) 340 (not (or executing-kbd-macro (bound-and-true-p edebug-active))))
326 341
327 342
@@ -347,6 +362,7 @@ variable) is taken into account if the major mode specific function does not
347return any documentation.") 362return any documentation.")
348 363
349(defun eldoc-print-current-symbol-info () 364(defun eldoc-print-current-symbol-info ()
365 "Print the text produced by `eldoc-documentation-function'."
350 ;; This is run from post-command-hook or some idle timer thing, 366 ;; This is run from post-command-hook or some idle timer thing,
351 ;; so we need to be careful that errors aren't ignored. 367 ;; so we need to be careful that errors aren't ignored.
352 (with-demoted-errors "eldoc error: %s" 368 (with-demoted-errors "eldoc error: %s"
@@ -361,6 +377,13 @@ return any documentation.")
361;; truncated or eliminated entirely from the output to make room for the 377;; truncated or eliminated entirely from the output to make room for the
362;; description. 378;; description.
363(defun eldoc-docstring-format-sym-doc (prefix doc &optional face) 379(defun eldoc-docstring-format-sym-doc (prefix doc &optional face)
380 "Combine PREFIX and DOC, and shorten the result to fit in the echo area.
381
382When PREFIX is a symbol, propertize its symbol name with FACE
383before combining it with DOC. If FACE is not provided, just
384apply the nil face.
385
386See also: `eldoc-echo-area-use-multiline-p'."
364 (when (symbolp prefix) 387 (when (symbolp prefix)
365 (setq prefix (concat (propertize (symbol-name prefix) 'face face) ": "))) 388 (setq prefix (concat (propertize (symbol-name prefix) 'face face) ": ")))
366 (let* ((ea-multi eldoc-echo-area-use-multiline-p) 389 (let* ((ea-multi eldoc-echo-area-use-multiline-p)
@@ -390,22 +413,26 @@ return any documentation.")
390;; These functions do display-command table management. 413;; These functions do display-command table management.
391 414
392(defun eldoc-add-command (&rest cmds) 415(defun eldoc-add-command (&rest cmds)
416 "Add each of CMDS to the obarray `eldoc-message-commands'."
393 (dolist (name cmds) 417 (dolist (name cmds)
394 (and (symbolp name) 418 (and (symbolp name)
395 (setq name (symbol-name name))) 419 (setq name (symbol-name name)))
396 (set (intern name eldoc-message-commands) t))) 420 (set (intern name eldoc-message-commands) t)))
397 421
398(defun eldoc-add-command-completions (&rest names) 422(defun eldoc-add-command-completions (&rest names)
423 "Pass every prefix completion of NAMES to `eldoc-add-command'."
399 (dolist (name names) 424 (dolist (name names)
400 (apply #'eldoc-add-command (all-completions name obarray 'commandp)))) 425 (apply #'eldoc-add-command (all-completions name obarray 'commandp))))
401 426
402(defun eldoc-remove-command (&rest cmds) 427(defun eldoc-remove-command (&rest cmds)
428 "Remove each of CMDS from the obarray `eldoc-message-commands'."
403 (dolist (name cmds) 429 (dolist (name cmds)
404 (and (symbolp name) 430 (and (symbolp name)
405 (setq name (symbol-name name))) 431 (setq name (symbol-name name)))
406 (unintern name eldoc-message-commands))) 432 (unintern name eldoc-message-commands)))
407 433
408(defun eldoc-remove-command-completions (&rest names) 434(defun eldoc-remove-command-completions (&rest names)
435 "Pass every prefix completion of NAMES to `eldoc-remove-command'."
409 (dolist (name names) 436 (dolist (name names)
410 (apply #'eldoc-remove-command 437 (apply #'eldoc-remove-command
411 (all-completions name eldoc-message-commands)))) 438 (all-completions name eldoc-message-commands))))
@@ -418,9 +445,9 @@ return any documentation.")
418 "down-list" "end-of-" "exchange-point-and-mark" "forward-" "goto-" 445 "down-list" "end-of-" "exchange-point-and-mark" "forward-" "goto-"
419 "handle-select-window" "indent-for-tab-command" "left-" "mark-page" 446 "handle-select-window" "indent-for-tab-command" "left-" "mark-page"
420 "mark-paragraph" "mouse-set-point" "move-" "move-beginning-of-" 447 "mark-paragraph" "mouse-set-point" "move-" "move-beginning-of-"
421 "move-end-of-" "newline" "next-" "other-window" "pop-global-mark" "previous-" 448 "move-end-of-" "newline" "next-" "other-window" "pop-global-mark"
422 "recenter" "right-" "scroll-" "self-insert-command" "split-window-" 449 "previous-" "recenter" "right-" "scroll-" "self-insert-command"
423 "up-list") 450 "split-window-" "up-list")
424 451
425(provide 'eldoc) 452(provide 'eldoc)
426 453
diff --git a/lisp/emacs-lisp/ert.el b/lisp/emacs-lisp/ert.el
index eb2b2e3e11b..5c88b070f65 100644
--- a/lisp/emacs-lisp/ert.el
+++ b/lisp/emacs-lisp/ert.el
@@ -136,8 +136,15 @@ Emacs bug 6581 at URL `http://debbugs.gnu.org/cgi/bugreport.cgi?bug=6581'."
136 ;; ert-test objects. It designates an anonymous test. 136 ;; ert-test objects. It designates an anonymous test.
137 (error "Attempt to define a test named nil")) 137 (error "Attempt to define a test named nil"))
138 (put symbol 'ert--test definition) 138 (put symbol 'ert--test definition)
139 ;; Register in load-history, so `symbol-file' can find us, and so
140 ;; unload-feature can unload our tests.
141 (cl-pushnew `(ert-deftest . ,symbol) current-load-list :test #'equal)
139 definition) 142 definition)
140 143
144(cl-defmethod loadhist-unload-element ((x (head ert-deftest)))
145 (let ((name (cdr x)))
146 (put name 'ert--test nil)))
147
141(defun ert-make-test-unbound (symbol) 148(defun ert-make-test-unbound (symbol)
142 "Make SYMBOL name no test. Return SYMBOL." 149 "Make SYMBOL name no test. Return SYMBOL."
143 (cl-remprop symbol 'ert--test) 150 (cl-remprop symbol 'ert--test)
@@ -214,12 +221,6 @@ description of valid values for RESULT-TYPE.
214 ,@(when tags-supplied-p 221 ,@(when tags-supplied-p
215 `(:tags ,tags)) 222 `(:tags ,tags))
216 :body (lambda () ,@body))) 223 :body (lambda () ,@body)))
217 ;; This hack allows `symbol-file' to associate `ert-deftest'
218 ;; forms with files, and therefore enables `find-function' to
219 ;; work with tests. However, it leads to warnings in
220 ;; `unload-feature', which doesn't know how to undefine tests
221 ;; and has no mechanism for extension.
222 (push '(ert-deftest . ,name) current-load-list)
223 ',name)))) 224 ',name))))
224 225
225;; We use these `put' forms in addition to the (declare (indent)) in 226;; We use these `put' forms in addition to the (declare (indent)) in
@@ -1512,7 +1513,7 @@ Ran \\([0-9]+\\) tests, \\([0-9]+\\) results as expected\
1512 (message "%d files contained unexpected results:" (length unexpected)) 1513 (message "%d files contained unexpected results:" (length unexpected))
1513 (mapc (lambda (l) (message " %s" l)) unexpected)) 1514 (mapc (lambda (l) (message " %s" l)) unexpected))
1514 ;; More details on hydra, where the logs are harder to get to. 1515 ;; More details on hydra, where the logs are harder to get to.
1515 (when (and (getenv "NIX_STORE") 1516 (when (and (getenv "EMACS_HYDRA_CI")
1516 (not (zerop (+ nunexpected nskipped)))) 1517 (not (zerop (+ nunexpected nskipped))))
1517 (message "\nDETAILS") 1518 (message "\nDETAILS")
1518 (message "-------") 1519 (message "-------")
diff --git a/lisp/emacs-lisp/gv.el b/lisp/emacs-lisp/gv.el
index c5c12a6414c..27376fc7f95 100644
--- a/lisp/emacs-lisp/gv.el
+++ b/lisp/emacs-lisp/gv.el
@@ -377,10 +377,12 @@ The return value is the last VAL in the list.
377 `(with-current-buffer ,buf (set (make-local-variable ,var) ,v)))) 377 `(with-current-buffer ,buf (set (make-local-variable ,var) ,v))))
378 378
379(gv-define-expander alist-get 379(gv-define-expander alist-get
380 (lambda (do key alist &optional default remove) 380 (lambda (do key alist &optional default remove testfn)
381 (macroexp-let2 macroexp-copyable-p k key 381 (macroexp-let2 macroexp-copyable-p k key
382 (gv-letplace (getter setter) alist 382 (gv-letplace (getter setter) alist
383 (macroexp-let2 nil p `(assq ,k ,getter) 383 (macroexp-let2 nil p `(if (and ,testfn (not (eq ,testfn 'eq)))
384 (assoc ,k ,getter ,testfn)
385 (assq ,k ,getter))
384 (funcall do (if (null default) `(cdr ,p) 386 (funcall do (if (null default) `(cdr ,p)
385 `(if ,p (cdr ,p) ,default)) 387 `(if ,p (cdr ,p) ,default))
386 (lambda (v) 388 (lambda (v)
diff --git a/lisp/emacs-lisp/map.el b/lisp/emacs-lisp/map.el
index a89457e877d..e098eef8294 100644
--- a/lisp/emacs-lisp/map.el
+++ b/lisp/emacs-lisp/map.el
@@ -4,7 +4,7 @@
4 4
5;; Author: Nicolas Petton <nicolas@petton.fr> 5;; Author: Nicolas Petton <nicolas@petton.fr>
6;; Keywords: convenience, map, hash-table, alist, array 6;; Keywords: convenience, map, hash-table, alist, array
7;; Version: 1.1 7;; Version: 1.2
8;; Package: map 8;; Package: map
9 9
10;; Maintainer: emacs-devel@gnu.org 10;; Maintainer: emacs-devel@gnu.org
@@ -93,11 +93,13 @@ Returns the result of evaluating the form associated with MAP-VAR's type."
93 ((arrayp ,map-var) ,(plist-get args :array)) 93 ((arrayp ,map-var) ,(plist-get args :array))
94 (t (error "Unsupported map: %s" ,map-var))))) 94 (t (error "Unsupported map: %s" ,map-var)))))
95 95
96(defun map-elt (map key &optional default) 96(defun map-elt (map key &optional default testfn)
97 "Lookup KEY in MAP and return its associated value. 97 "Lookup KEY in MAP and return its associated value.
98If KEY is not found, return DEFAULT which defaults to nil. 98If KEY is not found, return DEFAULT which defaults to nil.
99 99
100If MAP is a list, `eql' is used to lookup KEY. 100If MAP is a list, `eql' is used to lookup KEY. Optional argument
101TESTFN, if non-nil, means use its function definition instead of
102`eql'.
101 103
102MAP can be a list, hash-table or array." 104MAP can be a list, hash-table or array."
103 (declare 105 (declare
@@ -106,30 +108,31 @@ MAP can be a list, hash-table or array."
106 (gv-letplace (mgetter msetter) `(gv-delay-error ,map) 108 (gv-letplace (mgetter msetter) `(gv-delay-error ,map)
107 (macroexp-let2* nil 109 (macroexp-let2* nil
108 ;; Eval them once and for all in the right order. 110 ;; Eval them once and for all in the right order.
109 ((key key) (default default)) 111 ((key key) (default default) (testfn testfn))
110 `(if (listp ,mgetter) 112 `(if (listp ,mgetter)
111 ;; Special case the alist case, since it can't be handled by the 113 ;; Special case the alist case, since it can't be handled by the
112 ;; map--put function. 114 ;; map--put function.
113 ,(gv-get `(alist-get ,key (gv-synthetic-place 115 ,(gv-get `(alist-get ,key (gv-synthetic-place
114 ,mgetter ,msetter) 116 ,mgetter ,msetter)
115 ,default) 117 ,default nil ,testfn)
116 do) 118 do)
117 ,(funcall do `(map-elt ,mgetter ,key ,default) 119 ,(funcall do `(map-elt ,mgetter ,key ,default)
118 (lambda (v) `(map--put ,mgetter ,key ,v))))))))) 120 (lambda (v) `(map--put ,mgetter ,key ,v)))))))))
119 (map--dispatch map 121 (map--dispatch map
120 :list (alist-get key map default) 122 :list (alist-get key map default nil testfn)
121 :hash-table (gethash key map default) 123 :hash-table (gethash key map default)
122 :array (if (and (>= key 0) (< key (seq-length map))) 124 :array (if (and (>= key 0) (< key (seq-length map)))
123 (seq-elt map key) 125 (seq-elt map key)
124 default))) 126 default)))
125 127
126(defmacro map-put (map key value) 128(defmacro map-put (map key value &optional testfn)
127 "Associate KEY with VALUE in MAP and return VALUE. 129 "Associate KEY with VALUE in MAP and return VALUE.
128If KEY is already present in MAP, replace the associated value 130If KEY is already present in MAP, replace the associated value
129with VALUE. 131with VALUE.
132When MAP is a list, test equality with TESTFN if non-nil, otherwise use `eql'.
130 133
131MAP can be a list, hash-table or array." 134MAP can be a list, hash-table or array."
132 `(setf (map-elt ,map ,key) ,value)) 135 `(setf (map-elt ,map ,key nil ,testfn) ,value))
133 136
134(defun map-delete (map key) 137(defun map-delete (map key)
135 "Delete KEY from MAP and return MAP. 138 "Delete KEY from MAP and return MAP.
diff --git a/lisp/emacs-lisp/nadvice.el b/lisp/emacs-lisp/nadvice.el
index fd1cd2c7aaf..c68ecbc59ee 100644
--- a/lisp/emacs-lisp/nadvice.el
+++ b/lisp/emacs-lisp/nadvice.el
@@ -385,6 +385,18 @@ of the piece of advice."
385 385
386(defun advice--defalias-fset (fsetfun symbol newdef) 386(defun advice--defalias-fset (fsetfun symbol newdef)
387 (unless fsetfun (setq fsetfun #'fset)) 387 (unless fsetfun (setq fsetfun #'fset))
388 ;; `newdef' shouldn't include advice wrappers, since that's what *we* manage!
389 ;; So if `newdef' includes advice wrappers, it's usually because someone
390 ;; naively took (symbol-function F) and then passed that back to `defalias':
391 ;; let's strip them away.
392 (cond
393 ((advice--p newdef) (setq newdef (advice--cd*r newdef)))
394 ((and (eq 'macro (car-safe newdef))
395 (advice--p (cdr newdef)))
396 (setq newdef `(macro . ,(advice--cd*r (cdr newdef))))))
397 ;; The saved-rewrite is specific to the current value, so since we are about
398 ;; to overwrite that current value with new value, the old saved-rewrite is
399 ;; not relevant any more.
388 (when (get symbol 'advice--saved-rewrite) 400 (when (get symbol 'advice--saved-rewrite)
389 (put symbol 'advice--saved-rewrite nil)) 401 (put symbol 'advice--saved-rewrite nil))
390 (setq newdef (advice--normalize symbol newdef)) 402 (setq newdef (advice--normalize symbol newdef))
diff --git a/lisp/emacs-lisp/pcase.el b/lisp/emacs-lisp/pcase.el
index 4a06ab25d3e..b40161104d2 100644
--- a/lisp/emacs-lisp/pcase.el
+++ b/lisp/emacs-lisp/pcase.el
@@ -930,6 +930,5 @@ QPAT can take the following forms:
930 ((or (stringp qpat) (integerp qpat) (symbolp qpat)) `',qpat) 930 ((or (stringp qpat) (integerp qpat) (symbolp qpat)) `',qpat)
931 (t (error "Unknown QPAT: %S" qpat)))) 931 (t (error "Unknown QPAT: %S" qpat))))
932 932
933
934(provide 'pcase) 933(provide 'pcase)
935;;; pcase.el ends here 934;;; pcase.el ends here
diff --git a/lisp/emacs-lisp/rx.el b/lisp/emacs-lisp/rx.el
index 386232c6eef..b66f2c6d512 100644
--- a/lisp/emacs-lisp/rx.el
+++ b/lisp/emacs-lisp/rx.el
@@ -1169,6 +1169,62 @@ enclosed in `(and ...)'.
1169 (rx-to-string `(and ,@regexps) t)) 1169 (rx-to-string `(and ,@regexps) t))
1170 (t 1170 (t
1171 (rx-to-string (car regexps) t)))) 1171 (rx-to-string (car regexps) t))))
1172
1173
1174(pcase-defmacro rx (&rest regexps)
1175 "Build a `pcase' pattern matching `rx' regexps.
1176The REGEXPS are interpreted as by `rx'. The pattern matches if
1177the regular expression so constructed matches the object, as if
1178by `string-match'.
1179
1180In addition to the usual `rx' constructs, REGEXPS can contain the
1181following constructs:
1182
1183 (let VAR FORM...) creates a new explicitly numbered submatch
1184 that matches FORM and binds the match to
1185 VAR.
1186 (backref VAR) creates a backreference to the submatch
1187 introduced by a previous (let VAR ...)
1188 construct.
1189
1190The VARs are associated with explicitly numbered submatches
1191starting from 1. Multiple occurrences of the same VAR refer to
1192the same submatch.
1193
1194If a case matches, the match data is modified as usual so you can
1195use it in the case body, but you still have to pass the correct
1196string as argument to `match-string'."
1197 (let* ((vars ())
1198 (rx-constituents
1199 `((let
1200 ,(lambda (form)
1201 (rx-check form)
1202 (let ((var (cadr form)))
1203 (cl-check-type var symbol)
1204 (let ((i (or (cl-position var vars :test #'eq)
1205 (prog1 (length vars)
1206 (setq vars `(,@vars ,var))))))
1207 (rx-form `(submatch-n ,(1+ i) ,@(cddr form))))))
1208 1 nil)
1209 (backref
1210 ,(lambda (form)
1211 (rx-check form)
1212 (rx-backref
1213 `(backref ,(let ((var (cadr form)))
1214 (if (integerp var) var
1215 (1+ (cl-position var vars :test #'eq)))))))
1216 1 1
1217 ,(lambda (var)
1218 (cond ((integerp var) (rx-check-backref var))
1219 ((memq var vars) t)
1220 (t (error "rx `backref' variable must be one of %s: %s"
1221 vars var)))))
1222 ,@rx-constituents))
1223 (regexp (rx-to-string `(seq ,@regexps) :no-group)))
1224 `(and (pred (string-match ,regexp))
1225 ,@(cl-loop for i from 1
1226 for var in vars
1227 collect `(app (match-string ,i) ,var)))))
1172 1228
1173;; ;; sregex.el replacement 1229;; ;; sregex.el replacement
1174 1230
diff --git a/lisp/eshell/em-prompt.el b/lisp/eshell/em-prompt.el
index 8c81b43b1fa..2fd1db2113d 100644
--- a/lisp/eshell/em-prompt.el
+++ b/lisp/eshell/em-prompt.el
@@ -161,14 +161,25 @@ If N is negative, find the previous or Nth previous match."
161 "Move to end of Nth next prompt in the buffer. 161 "Move to end of Nth next prompt in the buffer.
162See `eshell-prompt-regexp'." 162See `eshell-prompt-regexp'."
163 (interactive "p") 163 (interactive "p")
164 (forward-paragraph n) 164 (if eshell-highlight-prompt
165 (progn
166 (while (< n 0)
167 (while (and (re-search-backward eshell-prompt-regexp nil t)
168 (not (get-text-property (match-beginning 0) 'read-only))))
169 (setq n (1+ n)))
170 (while (> n 0)
171 (while (and (re-search-forward eshell-prompt-regexp nil t)
172 (not (get-text-property (match-beginning 0) 'read-only))))
173 (setq n (1- n))))
174 (re-search-forward eshell-prompt-regexp nil t n))
165 (eshell-skip-prompt)) 175 (eshell-skip-prompt))
166 176
167(defun eshell-previous-prompt (n) 177(defun eshell-previous-prompt (n)
168 "Move to end of Nth previous prompt in the buffer. 178 "Move to end of Nth previous prompt in the buffer.
169See `eshell-prompt-regexp'." 179See `eshell-prompt-regexp'."
170 (interactive "p") 180 (interactive "p")
171 (eshell-next-prompt (- (1+ n)))) 181 (beginning-of-line) ; Don't count prompt on current line.
182 (eshell-next-prompt (- n)))
172 183
173(defun eshell-skip-prompt () 184(defun eshell-skip-prompt ()
174 "Skip past the text matching regexp `eshell-prompt-regexp'. 185 "Skip past the text matching regexp `eshell-prompt-regexp'.
diff --git a/lisp/faces.el b/lisp/faces.el
index 9a8a1344caf..97c32165b9c 100644
--- a/lisp/faces.el
+++ b/lisp/faces.el
@@ -102,11 +102,16 @@ a font height that isn't optimal."
102 ;; Monospace Serif is an Emacs invention, intended to work around 102 ;; Monospace Serif is an Emacs invention, intended to work around
103 ;; portability problems when using Courier. It should work well 103 ;; portability problems when using Courier. It should work well
104 ;; when combined with Monospaced and with other standard fonts. 104 ;; when combined with Monospaced and with other standard fonts.
105 ;; One of its uses is for 'tex-verbatim' and 'Info-quoted' faces,
106 ;; so the result must be different from the default face's font,
107 ;; and must be monospaced.
105 ("Monospace Serif" 108 ("Monospace Serif"
106 109
107 ;; This looks good on GNU/Linux. 110 ;; This looks good on GNU/Linux.
108 "Courier 10 Pitch" 111 "Courier 10 Pitch"
109 ;; This looks good on MS-Windows and OS X. 112 ;; This looks good on MS-Windows and OS X. Note that this is
113 ;; actually a sans-serif font, but it's here for lack of a better
114 ;; alternative.
110 "Consolas" 115 "Consolas"
111 ;; This looks good on macOS. "Courier" looks good too, but is 116 ;; This looks good on macOS. "Courier" looks good too, but is
112 ;; jagged on GNU/Linux and so is listed later as "courier". 117 ;; jagged on GNU/Linux and so is listed later as "courier".
@@ -2465,6 +2470,33 @@ If you set `term-file-prefix' to nil, this function does nothing."
2465 :version "21.1" 2470 :version "21.1"
2466 :group 'basic-faces) 2471 :group 'basic-faces)
2467 2472
2473;; Definition stolen from linum.el.
2474(defface line-number
2475 '((t :inherit (shadow default)))
2476 "Face for displaying line numbers.
2477This face is used when `display-line-numbers' is non-nil.
2478
2479If you customize the font of this face, make sure it is a
2480monospaced font, otherwise line numbers will not line up,
2481and text lines might move horizontally as you move through
2482the buffer."
2483 :version "26.1"
2484 :group 'basic-faces)
2485
2486(defface line-number-current-line
2487 '((t :inherit line-number))
2488 "Face for displaying the current line number.
2489This face is used when `display-line-numbers' is non-nil.
2490
2491If you customize the font of this face, make sure it is a
2492monospaced font, otherwise line numbers will not line up,
2493and text lines might move horizontally as you move through
2494the buffer. Similarly, making this face's font different
2495from that of the `line-number' face could produce such
2496unwanted effects."
2497 :version "26.1"
2498 :group 'basic-faces)
2499
2468(defface escape-glyph 2500(defface escape-glyph
2469 '((((background dark)) :foreground "cyan") 2501 '((((background dark)) :foreground "cyan")
2470 ;; See the comment in minibuffer-prompt for 2502 ;; See the comment in minibuffer-prompt for
diff --git a/lisp/files.el b/lisp/files.el
index 06f49bba23c..321a35b530d 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -434,8 +434,11 @@ and toggle it if ARG is `toggle'."
434 (not (and buffer-auto-save-file-name 434 (not (and buffer-auto-save-file-name
435 auto-save-visited-file-name))))))) 435 auto-save-visited-file-name)))))))
436 436
437;; The 'set' part is so we don't get a warning for using this variable
438;; above, while still catching code that _sets_ the variable to get
439;; the same effect as the new auto-save-visited-mode.
437(make-obsolete-variable 'auto-save-visited-file-name 'auto-save-visited-mode 440(make-obsolete-variable 'auto-save-visited-file-name 'auto-save-visited-mode
438 "Emacs 26.1") 441 "Emacs 26.1" 'set)
439 442
440(defcustom save-abbrevs t 443(defcustom save-abbrevs t
441 "Non-nil means save word abbrevs too when files are saved. 444 "Non-nil means save word abbrevs too when files are saved.
@@ -2540,7 +2543,7 @@ since only a single case-insensitive search through the alist is made."
2540 ("\\.[ckz]?sh\\'\\|\\.shar\\'\\|/\\.z?profile\\'" . sh-mode) 2543 ("\\.[ckz]?sh\\'\\|\\.shar\\'\\|/\\.z?profile\\'" . sh-mode)
2541 ("\\.bash\\'" . sh-mode) 2544 ("\\.bash\\'" . sh-mode)
2542 ("\\(/\\|\\`\\)\\.\\(bash_\\(profile\\|history\\|log\\(in\\|out\\)\\)\\|z?log\\(in\\|out\\)\\)\\'" . sh-mode) 2545 ("\\(/\\|\\`\\)\\.\\(bash_\\(profile\\|history\\|log\\(in\\|out\\)\\)\\|z?log\\(in\\|out\\)\\)\\'" . sh-mode)
2543 ("\\(/\\|\\`\\)\\.\\(shrc\\|[kz]shrc\\|bashrc\\|t?cshrc\\|esrc\\)\\'" . sh-mode) 2546 ("\\(/\\|\\`\\)\\.\\(shrc\\|zshrc\\|m?kshrc\\|bashrc\\|t?cshrc\\|esrc\\)\\'" . sh-mode)
2544 ("\\(/\\|\\`\\)\\.\\([kz]shenv\\|xinitrc\\|startxrc\\|xsession\\)\\'" . sh-mode) 2547 ("\\(/\\|\\`\\)\\.\\([kz]shenv\\|xinitrc\\|startxrc\\|xsession\\)\\'" . sh-mode)
2545 ("\\.m?spec\\'" . sh-mode) 2548 ("\\.m?spec\\'" . sh-mode)
2546 ("\\.m[mes]\\'" . nroff-mode) 2549 ("\\.m[mes]\\'" . nroff-mode)
diff --git a/lisp/frame.el b/lisp/frame.el
index b54df6fa160..634367edf45 100644
--- a/lisp/frame.el
+++ b/lisp/frame.el
@@ -1482,6 +1482,7 @@ FRAME."
1482 1482
1483(declare-function w32-mouse-absolute-pixel-position "w32fns.c") 1483(declare-function w32-mouse-absolute-pixel-position "w32fns.c")
1484(declare-function x-mouse-absolute-pixel-position "xfns.c") 1484(declare-function x-mouse-absolute-pixel-position "xfns.c")
1485(declare-function ns-mouse-absolute-pixel-position "nsfns.c")
1485 1486
1486(defun mouse-absolute-pixel-position () 1487(defun mouse-absolute-pixel-position ()
1487 "Return absolute position of mouse cursor in pixels. 1488 "Return absolute position of mouse cursor in pixels.
@@ -1494,6 +1495,8 @@ position (0, 0) of the selected frame's terminal."
1494 (x-mouse-absolute-pixel-position)) 1495 (x-mouse-absolute-pixel-position))
1495 ((eq frame-type 'w32) 1496 ((eq frame-type 'w32)
1496 (w32-mouse-absolute-pixel-position)) 1497 (w32-mouse-absolute-pixel-position))
1498 ((eq frame-type 'ns)
1499 (ns-mouse-absolute-pixel-position))
1497 (t 1500 (t
1498 (cons 0 0))))) 1501 (cons 0 0)))))
1499 1502
@@ -2458,7 +2461,13 @@ See also `toggle-frame-maximized'."
2458(make-obsolete-variable 2461(make-obsolete-variable
2459 'window-system-version "it does not give useful information." "24.3") 2462 'window-system-version "it does not give useful information." "24.3")
2460 2463
2461;; Variables which should trigger redisplay of the current buffer. 2464;; Variables whose change of value should trigger redisplay of the
2465;; current buffer.
2466;; To test whether a given variable needs to be added to this list,
2467;; write a simple interactive function that changes the variable's
2468;; value and bind that function to a simple key, like F5. If typing
2469;; F5 then produces the correct effect, the variable doesn't need
2470;; to be in this list; otherwise, it does.
2462(mapc (lambda (var) 2471(mapc (lambda (var)
2463 (add-variable-watcher var (symbol-function 'set-buffer-redisplay))) 2472 (add-variable-watcher var (symbol-function 'set-buffer-redisplay)))
2464 '(line-spacing 2473 '(line-spacing
@@ -2466,6 +2475,10 @@ See also `toggle-frame-maximized'."
2466 line-prefix 2475 line-prefix
2467 wrap-prefix 2476 wrap-prefix
2468 truncate-lines 2477 truncate-lines
2478 display-line-numbers
2479 display-line-numbers-width
2480 display-line-numbers-current-absolute
2481 display-line-numbers-widen
2469 bidi-paragraph-direction 2482 bidi-paragraph-direction
2470 bidi-display-reordering)) 2483 bidi-display-reordering))
2471 2484
diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el
index 9bdd0c66f56..f2e51fb225f 100644
--- a/lisp/gnus/gnus-sum.el
+++ b/lisp/gnus/gnus-sum.el
@@ -9780,8 +9780,11 @@ If ARG is a negative number, hide the unwanted header lines."
9780 (inhibit-point-motion-hooks t) 9780 (inhibit-point-motion-hooks t)
9781 (hidden (if (numberp arg) 9781 (hidden (if (numberp arg)
9782 (>= arg 0) 9782 (>= arg 0)
9783 (or (not (looking-at "[^ \t\n]+:")) 9783 (or
9784 (gnus-article-hidden-text-p 'headers)))) 9784 ;; The case where there's no visible header
9785 ;; that matches `gnus-visible-headers'.
9786 (looking-at "\n?\\'")
9787 (gnus-article-hidden-text-p 'headers))))
9785 s e) 9788 s e)
9786 (delete-region (point-min) (point-max)) 9789 (delete-region (point-min) (point-max))
9787 (with-current-buffer gnus-original-article-buffer 9790 (with-current-buffer gnus-original-article-buffer
diff --git a/lisp/help-fns.el b/lisp/help-fns.el
index f5d94d8419f..cb0b2d71d33 100644
--- a/lisp/help-fns.el
+++ b/lisp/help-fns.el
@@ -564,7 +564,6 @@ FILE is the file where FUNCTION was probably defined."
564 "Return information about FUNCTION. 564 "Return information about FUNCTION.
565Returns a list of the form (REAL-FUNCTION DEF ALIASED REAL-DEF)." 565Returns a list of the form (REAL-FUNCTION DEF ALIASED REAL-DEF)."
566 (let* ((advised (and (symbolp function) 566 (let* ((advised (and (symbolp function)
567 (featurep 'nadvice)
568 (advice--p (advice--symbol-function function)))) 567 (advice--p (advice--symbol-function function))))
569 ;; If the function is advised, use the symbol that has the 568 ;; If the function is advised, use the symbol that has the
570 ;; real definition, if that symbol is already set up. 569 ;; real definition, if that symbol is already set up.
diff --git a/lisp/help.el b/lisp/help.el
index 0fb1c2dab77..bc7ee2c9b1b 100644
--- a/lisp/help.el
+++ b/lisp/help.el
@@ -1384,6 +1384,9 @@ If PRESERVE-NAMES is non-nil, return a formal arglist that uses
1384the same names as used in the original source code, when possible." 1384the same names as used in the original source code, when possible."
1385 ;; Handle symbols aliased to other symbols. 1385 ;; Handle symbols aliased to other symbols.
1386 (if (and (symbolp def) (fboundp def)) (setq def (indirect-function def))) 1386 (if (and (symbolp def) (fboundp def)) (setq def (indirect-function def)))
1387 ;; Advice wrappers have "catch all" args, so fetch the actual underlying
1388 ;; function to find the real arguments.
1389 (while (advice--p def) (setq def (advice--cdr def)))
1387 ;; If definition is a macro, find the function inside it. 1390 ;; If definition is a macro, find the function inside it.
1388 (if (eq (car-safe def) 'macro) (setq def (cdr def))) 1391 (if (eq (car-safe def) 'macro) (setq def (cdr def)))
1389 (cond 1392 (cond
diff --git a/lisp/international/characters.el b/lisp/international/characters.el
index 33cb3d85223..e48fc83c3df 100644
--- a/lisp/international/characters.el
+++ b/lisp/international/characters.el
@@ -148,6 +148,7 @@ with L, LRE, or LRO Unicode bidi character type.")
148(modify-category-entry '(#xF900 . #xFAFF) ?C) 148(modify-category-entry '(#xF900 . #xFAFF) ?C)
149(modify-category-entry '(#xF900 . #xFAFF) ?c) 149(modify-category-entry '(#xF900 . #xFAFF) ?c)
150(modify-category-entry '(#xF900 . #xFAFF) ?|) 150(modify-category-entry '(#xF900 . #xFAFF) ?|)
151(modify-category-entry '(#x1B170 . #x1B2FF) ?c)
151(modify-category-entry '(#x20000 . #x2FFFF) ?|) 152(modify-category-entry '(#x20000 . #x2FFFF) ?|)
152(modify-category-entry '(#x20000 . #x2FFFF) ?C) 153(modify-category-entry '(#x20000 . #x2FFFF) ?C)
153(modify-category-entry '(#x20000 . #x2FFFF) ?c) 154(modify-category-entry '(#x20000 . #x2FFFF) ?c)
@@ -221,6 +222,8 @@ with L, LRE, or LRO Unicode bidi character type.")
221(modify-category-entry #x30A0 ?H) 222(modify-category-entry #x30A0 ?H)
222(modify-category-entry #x30FC ?H) 223(modify-category-entry #x30FC ?H)
223 224
225(modify-category-entry '(#x1B000 . #x1B1FF) ?j)
226
224 227
225;; JISX0208 228;; JISX0208
226(map-charset-chars #'modify-syntax-entry 'japanese-jisx0208 "_" #x2121 #x227E) 229(map-charset-chars #'modify-syntax-entry 'japanese-jisx0208 "_" #x2121 #x227E)
@@ -1196,10 +1199,11 @@ with L, LRE, or LRO Unicode bidi character type.")
1196 (#xFE30 . #xFE6F) 1199 (#xFE30 . #xFE6F)
1197 (#xFF01 . #xFF60) 1200 (#xFF01 . #xFF60)
1198 (#xFFE0 . #xFFE6) 1201 (#xFFE0 . #xFFE6)
1199 (#x16FE0 . #x16FE0) 1202 (#x16FE0 . #x16FE1)
1200 (#x17000 . #x187EC) 1203 (#x17000 . #x187EC)
1201 (#x18800 . #x18AF2) 1204 (#x18800 . #x18AF2)
1202 (#x1B000 . #x1B001) 1205 (#x1B000 . #x1B11E)
1206 (#x1B170 . #x1B2FB)
1203 (#x1F004 . #x1F004) 1207 (#x1F004 . #x1F004)
1204 (#x1F0CF . #x1F0CF) 1208 (#x1F0CF . #x1F0CF)
1205 (#x1F18E . #x1F18E) 1209 (#x1F18E . #x1F18E)
@@ -1229,15 +1233,13 @@ with L, LRE, or LRO Unicode bidi character type.")
1229 (#x1F6CC . #x1F6CC) 1233 (#x1F6CC . #x1F6CC)
1230 (#x1F6D0 . #x1F6D2) 1234 (#x1F6D0 . #x1F6D2)
1231 (#x1F6EB . #x1F6EC) 1235 (#x1F6EB . #x1F6EC)
1232 (#x1F6F4 . #x1F6F6) 1236 (#x1F6F4 . #x1F6F8)
1233 (#x1F910 . #x1F91E) 1237 (#x1F910 . #x1F93E)
1234 (#x1F920 . #x1F927) 1238 (#x1F940 . #x1F94C)
1235 (#x1F930 . #x1F930) 1239 (#x1F950 . #x1F96B)
1236 (#x1F933 . #x1F93E) 1240 (#x1F980 . #x1F997)
1237 (#x1F940 . #x1F94B)
1238 (#x1F950 . #x1F95E)
1239 (#x1F980 . #x1F991)
1240 (#x1F9C0 . #x1F9C0) 1241 (#x1F9C0 . #x1F9C0)
1242 (#x1F9D0 . #x1F9E6)
1241 (#x20000 . #x2FFFF) 1243 (#x20000 . #x2FFFF)
1242 (#x30000 . #x3FFFF)))) 1244 (#x30000 . #x3FFFF))))
1243 (dolist (elt l) 1245 (dolist (elt l)
diff --git a/lisp/international/fontset.el b/lisp/international/fontset.el
index e023d253693..8a1a9cfc58b 100644
--- a/lisp/international/fontset.el
+++ b/lisp/international/fontset.el
@@ -227,9 +227,12 @@
227 (modi #x11600) 227 (modi #x11600)
228 (takri #x11680) 228 (takri #x11680)
229 (warang-citi #x118A1) 229 (warang-citi #x118A1)
230 (zanabazar-square #x11A00)
231 (soyombo #x11A50)
230 (pau-cin-hau #x11AC0) 232 (pau-cin-hau #x11AC0)
231 (bhaiksuki #x11C00) 233 (bhaiksuki #x11C00)
232 (marchen #x11C72) 234 (marchen #x11C72)
235 (masaram-gondi #x11D00)
233 (cuneiform #x12000) 236 (cuneiform #x12000)
234 (cuneiform-numbers-and-punctuation #x12400) 237 (cuneiform-numbers-and-punctuation #x12400)
235 (mro #x16A40) 238 (mro #x16A40)
@@ -237,6 +240,7 @@
237 (pahawh-hmong #x16B11) 240 (pahawh-hmong #x16B11)
238 (tangut #x17000) 241 (tangut #x17000)
239 (tangut-components #x18800) 242 (tangut-components #x18800)
243 (nushu #x1B170)
240 (duployan-shorthand #x1BC20) 244 (duployan-shorthand #x1BC20)
241 (byzantine-musical-symbol #x1D000) 245 (byzantine-musical-symbol #x1D000)
242 (musical-symbol #x1D100) 246 (musical-symbol #x1D100)
diff --git a/lisp/international/mule-cmds.el b/lisp/international/mule-cmds.el
index bdba8eeb112..bcbc92844d6 100644
--- a/lisp/international/mule-cmds.el
+++ b/lisp/international/mule-cmds.el
@@ -2945,8 +2945,10 @@ on encoding."
2945 ;; (#x17000 . #x187FF) Tangut Ideographs 2945 ;; (#x17000 . #x187FF) Tangut Ideographs
2946 ;; (#x18800 . #x18AFF) Tangut Components 2946 ;; (#x18800 . #x18AFF) Tangut Components
2947 ;; (#x18B00 . #x1AFFF) unused 2947 ;; (#x18B00 . #x1AFFF) unused
2948 (#x1B000 . #x1B0FF) 2948 (#x1B000 . #x1B12F)
2949 ;; (#x1B100 . #x1BBFF) unused 2949 ;; (#x1B130 . #x1B16F) unused
2950 (#x1B170 . #x1B2FF)
2951 ;; (#x1B300 . #x1BBFF) unused
2950 (#x1BC00 . #x1BCAF) 2952 (#x1BC00 . #x1BCAF)
2951 ;; (#x1BCB0 . #x1CFFF) unused 2953 ;; (#x1BCB0 . #x1CFFF) unused
2952 (#x1D000 . #x1FFFF) 2954 (#x1D000 . #x1FFFF)
diff --git a/lisp/kmacro.el b/lisp/kmacro.el
index 838a492b6cb..472972e3edb 100644
--- a/lisp/kmacro.el
+++ b/lisp/kmacro.el
@@ -565,7 +565,8 @@ Use \\[kmacro-insert-counter] to insert (and increment) the macro counter.
565The counter value can be set or modified via \\[kmacro-set-counter] and \\[kmacro-add-counter]. 565The counter value can be set or modified via \\[kmacro-set-counter] and \\[kmacro-add-counter].
566The format of the counter can be modified via \\[kmacro-set-format]. 566The format of the counter can be modified via \\[kmacro-set-format].
567 567
568Use \\[kmacro-name-last-macro] to give it a permanent name. 568Use \\[kmacro-name-last-macro] to give it a name that will remain valid even
569after another macro is defined.
569Use \\[kmacro-bind-to-key] to bind it to a key sequence." 570Use \\[kmacro-bind-to-key] to bind it to a key sequence."
570 (interactive "P") 571 (interactive "P")
571 (if (or defining-kbd-macro executing-kbd-macro) 572 (if (or defining-kbd-macro executing-kbd-macro)
@@ -628,8 +629,8 @@ just the last key in the key sequence that you used to call this
628command. See `kmacro-call-repeat-key' and `kmacro-call-repeat-with-arg' 629command. See `kmacro-call-repeat-key' and `kmacro-call-repeat-with-arg'
629for details on how to adjust or disable this behavior. 630for details on how to adjust or disable this behavior.
630 631
631To make a macro permanent so you can call it even after defining 632To give a macro a name so you can call it even after defining others,
632others, use \\[kmacro-name-last-macro]." 633use \\[kmacro-name-last-macro]."
633 (interactive "p") 634 (interactive "p")
634 (let ((repeat-key (and (or (and (null no-repeat) 635 (let ((repeat-key (and (or (and (null no-repeat)
635 (> (length (this-single-command-keys)) 1)) 636 (> (length (this-single-command-keys)) 1))
@@ -730,8 +731,8 @@ With \\[universal-argument], call second macro in macro ring."
730With numeric prefix ARG, repeat macro that many times. 731With numeric prefix ARG, repeat macro that many times.
731Zero argument means repeat until there is an error. 732Zero argument means repeat until there is an error.
732 733
733To give a macro a permanent name, so you can call it 734To give a macro a name, so you can call it even after defining other
734even after defining other macros, use \\[kmacro-name-last-macro]." 735macros, use \\[kmacro-name-last-macro]."
735 (interactive "P") 736 (interactive "P")
736 (if defining-kbd-macro 737 (if defining-kbd-macro
737 (kmacro-end-macro nil)) 738 (kmacro-end-macro nil))
diff --git a/lisp/leim/quail/latin-alt.el b/lisp/leim/quail/latin-alt.el
index 6c0dab28b41..cc721343c55 100644
--- a/lisp/leim/quail/latin-alt.el
+++ b/lisp/leim/quail/latin-alt.el
@@ -1152,7 +1152,7 @@ Doubling the postfix separates the letter and postfix: e.g. a^^ -> a^
1152(quail-define-package 1152(quail-define-package
1153 "dutch" "Dutch" "NL" t 1153 "dutch" "Dutch" "NL" t
1154 "Dutch character mixfix input method. 1154 "Dutch character mixfix input method.
1155Caters for French and Turkish as well as Dutch. 1155Caters for French and Dutch.
1156 1156
1157 | | examples 1157 | | examples
1158 ------------+---------+---------- 1158 ------------+---------+----------
@@ -1163,8 +1163,6 @@ Caters for French and Turkish as well as Dutch.
1163 acute | \\=' | a\\=' -> á 1163 acute | \\=' | a\\=' -> á
1164 grave | \\=` | a\\=` -> à 1164 grave | \\=` | a\\=` -> à
1165 circumflex | ^ | a^ -> â 1165 circumflex | ^ | a^ -> â
1166 Turkish | various | i/ -> ı s, -> ş g^ -> ğ I/ -> İ
1167 | | S, -> Ş G^ -> Ğ
1168 ------------+---------+---------- 1166 ------------+---------+----------
1169 | prefix | 1167 | prefix |
1170 ------------+---------+---------- 1168 ------------+---------+----------
@@ -1176,9 +1174,6 @@ Doubling the postfix separates the letter and postfix: e.g. a\\='\\=' -> a\\='
1176(quail-define-rules 1174(quail-define-rules
1177 ("fl." ?ƒ) ;; LATIN SMALL LETTER F WITH HOOK (florin currency symbol) 1175 ("fl." ?ƒ) ;; LATIN SMALL LETTER F WITH HOOK (florin currency symbol)
1178 ("eur." ?€) ;; EURO SIGN 1176 ("eur." ?€) ;; EURO SIGN
1179 ;; “The 25th letter of the Dutch alphabet.”
1180 ("ij" ?ij) ;; LATIN SMALL LIGATURE IJ
1181 ("IJ" ?IJ) ;; LATIN CAPITAL LIGATURE IJ
1182 ;; “Trema on the second letter of vowel pair.” Yudit uses `:', not `"'. 1177 ;; “Trema on the second letter of vowel pair.” Yudit uses `:', not `"'.
1183 ("\"a" ?ä) ;; LATIN SMALL LETTER A WITH DIAERESIS 1178 ("\"a" ?ä) ;; LATIN SMALL LETTER A WITH DIAERESIS
1184 ("\"e" ?ë) ;; LATIN SMALL LETTER E WITH DIAERESIS 1179 ("\"e" ?ë) ;; LATIN SMALL LETTER E WITH DIAERESIS
@@ -1226,15 +1221,6 @@ Doubling the postfix separates the letter and postfix: e.g. a\\='\\=' -> a\\='
1226 ("I^" ?Î) ;; LATIN CAPITAL LETTER I WITH CIRCUMFLEX 1221 ("I^" ?Î) ;; LATIN CAPITAL LETTER I WITH CIRCUMFLEX
1227 ("O^" ?Ô) ;; LATIN CAPITAL LETTER O WITH CIRCUMFLEX 1222 ("O^" ?Ô) ;; LATIN CAPITAL LETTER O WITH CIRCUMFLEX
1228 ("U^" ?Û) ;; LATIN CAPITAL LETTER U WITH CIRCUMFLEX 1223 ("U^" ?Û) ;; LATIN CAPITAL LETTER U WITH CIRCUMFLEX
1229 ;; “Follow the example of the Dutch POSIX locale, using ISO-8859-9 to
1230 ;; cater to the many Turks in Dutch society.” Perhaps German methods
1231 ;; should do so too. Follow turkish-alt-postfix here.
1232 ("i/" ?ı) ;; LATIN SMALL LETTER I WITH NO DOT
1233 ("s," ?ş) ;; LATIN SMALL LETTER S WITH CEDILLA
1234 ("g^" ?ğ) ;; LATIN SMALL LETTER G WITH BREVE
1235 ("I/" ?İ) ;; LATIN CAPITAL LETTER I WITH DOT ABOVE
1236 ("S," ?Ş) ;; LATIN CAPITAL LETTER S WITH CEDILLA
1237 ("G^" ?Ğ) ;; LATIN CAPITAL LETTER G WITH BREVE
1238 ) 1224 )
1239 1225
1240;; Originally from Yudit, discussed with Albertas Agejevas 1226;; Originally from Yudit, discussed with Albertas Agejevas
diff --git a/lisp/loadhist.el b/lisp/loadhist.el
index 28d0b18c812..24c3acd1b99 100644
--- a/lisp/loadhist.el
+++ b/lisp/loadhist.el
@@ -162,6 +162,65 @@ documentation of `unload-feature' for details.")
162 ;; mode, or proposed is not nil and not major-mode, and so we use it. 162 ;; mode, or proposed is not nil and not major-mode, and so we use it.
163 (funcall (or proposed 'fundamental-mode))))))) 163 (funcall (or proposed 'fundamental-mode)))))))
164 164
165(cl-defgeneric loadhist-unload-element (x)
166 "Unload an element from the `load-history'."
167 (message "Unexpected element %S in load-history" x))
168
169;; In `load-history', the definition of a previously autoloaded
170;; function is represented by 2 entries: (t . SYMBOL) comes before
171;; (defun . SYMBOL) and says we should restore SYMBOL's autoload when
172;; we undefine it.
173;; So we use this auxiliary variable to keep track of the last (t . SYMBOL)
174;; that occurred.
175(defvar loadhist--restore-autoload
176 "If non-nil, this is a symbol for which we should
177restore a previous autoload if possible.")
178
179(cl-defmethod loadhist-unload-element ((x (head t)))
180 (setq loadhist--restore-autoload (cdr x)))
181
182(defun loadhist--unload-function (x)
183 (let ((fun (cdr x)))
184 (when (fboundp fun)
185 (when (fboundp 'ad-unadvise)
186 (ad-unadvise fun))
187 (let ((aload (get fun 'autoload)))
188 (defalias fun
189 (if (and aload (eq fun loadhist--restore-autoload))
190 (cons 'autoload aload)
191 nil)))))
192 (setq loadhist--restore-autoload nil))
193
194(cl-defmethod loadhist-unload-element ((x (head defun)))
195 (loadhist--unload-function x))
196(cl-defmethod loadhist-unload-element ((x (head autoload)))
197 (loadhist--unload-function x))
198
199(cl-defmethod loadhist-unload-element ((_ (head require))) nil)
200(cl-defmethod loadhist-unload-element ((_ (head defface))) nil)
201
202(cl-defmethod loadhist-unload-element ((x (head provide)))
203 ;; Remove any feature names that this file provided.
204 (setq features (delq (cdr x) features)))
205
206(cl-defmethod loadhist-unload-element ((x symbol))
207 ;; Kill local values as much as possible.
208 (dolist (buf (buffer-list))
209 (with-current-buffer buf
210 (if (and (boundp x) (timerp (symbol-value x)))
211 (cancel-timer (symbol-value x)))
212 (kill-local-variable x)))
213 (if (and (boundp x) (timerp (symbol-value x)))
214 (cancel-timer (symbol-value x)))
215 ;; Get rid of the default binding if we can.
216 (unless (local-variable-if-set-p x)
217 (makunbound x)))
218
219(cl-defmethod loadhist-unload-element ((x (head define-type)))
220 (let* ((name (cdr x)))
221 ;; Remove the struct.
222 (setf (cl--find-class name) nil)))
223
165;;;###autoload 224;;;###autoload
166(defun unload-feature (feature &optional force) 225(defun unload-feature (feature &optional force)
167 "Unload the library that provided FEATURE. 226 "Unload the library that provided FEATURE.
@@ -200,9 +259,6 @@ something strange, such as redefining an Emacs function."
200 (prin1-to-string dependents) file)))) 259 (prin1-to-string dependents) file))))
201 (let* ((unload-function-defs-list (feature-symbols feature)) 260 (let* ((unload-function-defs-list (feature-symbols feature))
202 (file (pop unload-function-defs-list)) 261 (file (pop unload-function-defs-list))
203 ;; If non-nil, this is a symbol for which we should
204 ;; restore a previous autoload if possible.
205 restore-autoload
206 (name (symbol-name feature)) 262 (name (symbol-name feature))
207 (unload-hook (intern-soft (concat name "-unload-hook"))) 263 (unload-hook (intern-soft (concat name "-unload-hook")))
208 (unload-func (intern-soft (concat name "-unload-function")))) 264 (unload-func (intern-soft (concat name "-unload-function"))))
@@ -250,38 +306,7 @@ something strange, such as redefining an Emacs function."
250 (when (symbolp elt) 306 (when (symbolp elt)
251 (elp-restore-function elt)))) 307 (elp-restore-function elt))))
252 308
253 (dolist (x unload-function-defs-list) 309 (mapc #'loadhist-unload-element unload-function-defs-list)
254 (if (consp x)
255 (pcase (car x)
256 ;; Remove any feature names that this file provided.
257 (`provide
258 (setq features (delq (cdr x) features)))
259 ((or `defun `autoload)
260 (let ((fun (cdr x)))
261 (when (fboundp fun)
262 (when (fboundp 'ad-unadvise)
263 (ad-unadvise fun))
264 (let ((aload (get fun 'autoload)))
265 (if (and aload (eq fun restore-autoload))
266 (fset fun (cons 'autoload aload))
267 (fmakunbound fun))))))
268 ;; (t . SYMBOL) comes before (defun . SYMBOL)
269 ;; and says we should restore SYMBOL's autoload
270 ;; when we undefine it.
271 (`t (setq restore-autoload (cdr x)))
272 ((or `require `defface) nil)
273 (_ (message "Unexpected element %s in load-history" x)))
274 ;; Kill local values as much as possible.
275 (dolist (buf (buffer-list))
276 (with-current-buffer buf
277 (if (and (boundp x) (timerp (symbol-value x)))
278 (cancel-timer (symbol-value x)))
279 (kill-local-variable x)))
280 (if (and (boundp x) (timerp (symbol-value x)))
281 (cancel-timer (symbol-value x)))
282 ;; Get rid of the default binding if we can.
283 (unless (local-variable-if-set-p x)
284 (makunbound x))))
285 ;; Delete the load-history element for this file. 310 ;; Delete the load-history element for this file.
286 (setq load-history (delq (assoc file load-history) load-history)))) 311 (setq load-history (delq (assoc file load-history) load-history))))
287 ;; Don't return load-history, it is not useful. 312 ;; Don't return load-history, it is not useful.
diff --git a/lisp/ls-lisp.el b/lisp/ls-lisp.el
index 7ae23434415..b368efbbc95 100644
--- a/lisp/ls-lisp.el
+++ b/lisp/ls-lisp.el
@@ -245,11 +245,11 @@ to fail to line up, e.g. if month names are not all of the same length."
245 "Format to display integer GIDs.") 245 "Format to display integer GIDs.")
246(defvar ls-lisp-gid-s-fmt " %s" 246(defvar ls-lisp-gid-s-fmt " %s"
247 "Format to display user group names.") 247 "Format to display user group names.")
248(defvar ls-lisp-filesize-d-fmt "%d" 248(defvar ls-lisp-filesize-d-fmt " %d"
249 "Format to display integer file sizes.") 249 "Format to display integer file sizes.")
250(defvar ls-lisp-filesize-f-fmt "%.0f" 250(defvar ls-lisp-filesize-f-fmt " %.0f"
251 "Format to display float file sizes.") 251 "Format to display float file sizes.")
252(defvar ls-lisp-filesize-b-fmt "%.0f" 252(defvar ls-lisp-filesize-b-fmt " %.0f"
253 "Format to display file sizes in blocks (for the -s switch).") 253 "Format to display file sizes in blocks (for the -s switch).")
254 254
255;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 255;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
diff --git a/lisp/mail/rmail.el b/lisp/mail/rmail.el
index df07140d87b..b2405882896 100644
--- a/lisp/mail/rmail.el
+++ b/lisp/mail/rmail.el
@@ -2828,8 +2828,6 @@ The current mail message becomes the message displayed."
2828 (re-search-forward "mime-version: 1.0" nil t)) 2828 (re-search-forward "mime-version: 1.0" nil t))
2829 (let ((rmail-buffer mbox-buf) 2829 (let ((rmail-buffer mbox-buf)
2830 (rmail-view-buffer view-buf)) 2830 (rmail-view-buffer view-buf))
2831 (setq showing-message t)
2832 (message "Showing message %d..." msg)
2833 (set (make-local-variable 'rmail-mime-decoded) t) 2831 (set (make-local-variable 'rmail-mime-decoded) t)
2834 (funcall rmail-show-mime-function)) 2832 (funcall rmail-show-mime-function))
2835 (setq body-start (search-forward "\n\n" nil t)) 2833 (setq body-start (search-forward "\n\n" nil t))
diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el
index 9c7bcffbaab..05a336bfe28 100644
--- a/lisp/menu-bar.el
+++ b/lisp/menu-bar.el
@@ -1101,17 +1101,77 @@ The selected font will be the default on both the existing and future frames."
1101 :button (:radio . (eq tool-bar-mode nil)))) 1101 :button (:radio . (eq tool-bar-mode nil))))
1102 menu))) 1102 menu)))
1103 1103
1104(defun menu-bar-display-line-numbers-mode (type)
1105 (setq display-line-numbers-type type)
1106 (if global-display-line-numbers-mode
1107 (global-display-line-numbers-mode)
1108 (display-line-numbers-mode)))
1109
1110(defvar menu-bar-showhide-line-numbers-menu
1111 (let ((menu (make-sparse-keymap "Line Numbers")))
1112
1113 (bindings--define-key menu [visual]
1114 `(menu-item "Visual Line Numbers"
1115 ,(lambda ()
1116 (interactive)
1117 (menu-bar-display-line-numbers-mode 'visual)
1118 (message "Visual line numbers enabled"))
1119 :help "Enable visual line numbers"
1120 :button (:radio . (eq display-line-numbers 'visual))
1121 :visible (menu-bar-menu-frame-live-and-visible-p)))
1122
1123 (bindings--define-key menu [relative]
1124 `(menu-item "Relative Line Numbers"
1125 ,(lambda ()
1126 (interactive)
1127 (menu-bar-display-line-numbers-mode 'relative)
1128 (message "Relative line numbers enabled"))
1129 :help "Enable relative line numbers"
1130 :button (:radio . (eq display-line-numbers 'relative))
1131 :visible (menu-bar-menu-frame-live-and-visible-p)))
1132
1133 (bindings--define-key menu [absolute]
1134 `(menu-item "Absolute Line Numbers"
1135 ,(lambda ()
1136 (interactive)
1137 (menu-bar-display-line-numbers-mode t)
1138 (setq display-line-numbers t)
1139 (message "Absolute line numbers enabled"))
1140 :help "Enable absolute line numbers"
1141 :button (:radio . (eq display-line-numbers t))
1142 :visible (menu-bar-menu-frame-live-and-visible-p)))
1143
1144 (bindings--define-key menu [none]
1145 `(menu-item "No Line Numbers"
1146 ,(lambda ()
1147 (interactive)
1148 (menu-bar-display-line-numbers-mode nil)
1149 (message "Line numbers disabled"))
1150 :help "Disable line numbers"
1151 :button (:radio . (null display-line-numbers))
1152 :visible (menu-bar-menu-frame-live-and-visible-p)))
1153
1154 (bindings--define-key menu [global]
1155 (menu-bar-make-mm-toggle global-display-line-numbers-mode
1156 "Global Line Numbers Mode"
1157 "Set line numbers globally"))
1158 menu))
1159
1104(defvar menu-bar-showhide-menu 1160(defvar menu-bar-showhide-menu
1105 (let ((menu (make-sparse-keymap "Show/Hide"))) 1161 (let ((menu (make-sparse-keymap "Show/Hide")))
1106 1162
1163 (bindings--define-key menu [display-line-numbers]
1164 `(menu-item "Line Numbers for All Lines"
1165 ,menu-bar-showhide-line-numbers-menu))
1166
1107 (bindings--define-key menu [column-number-mode] 1167 (bindings--define-key menu [column-number-mode]
1108 (menu-bar-make-mm-toggle column-number-mode 1168 (menu-bar-make-mm-toggle column-number-mode
1109 "Column Numbers" 1169 "Column Numbers in Mode Line"
1110 "Show the current column number in the mode line")) 1170 "Show the current column number in the mode line"))
1111 1171
1112 (bindings--define-key menu [line-number-mode] 1172 (bindings--define-key menu [line-number-mode]
1113 (menu-bar-make-mm-toggle line-number-mode 1173 (menu-bar-make-mm-toggle line-number-mode
1114 "Line Numbers" 1174 "Line Numbers in Mode Line"
1115 "Show the current line number in the mode line")) 1175 "Show the current line number in the mode line"))
1116 1176
1117 (bindings--define-key menu [size-indication-mode] 1177 (bindings--define-key menu [size-indication-mode]
diff --git a/lisp/net/shr.el b/lisp/net/shr.el
index 4d4e8a809e1..fe93fc32ad3 100644
--- a/lisp/net/shr.el
+++ b/lisp/net/shr.el
@@ -945,6 +945,7 @@ If EXTERNAL, browse the URL using `shr-external-browser'."
945 (when (and (buffer-name buffer) 945 (when (and (buffer-name buffer)
946 (not (plist-get status :error))) 946 (not (plist-get status :error)))
947 (url-store-in-cache image-buffer) 947 (url-store-in-cache image-buffer)
948 (goto-char (point-min))
948 (when (or (search-forward "\n\n" nil t) 949 (when (or (search-forward "\n\n" nil t)
949 (search-forward "\r\n\r\n" nil t)) 950 (search-forward "\r\n\r\n" nil t))
950 (let ((data (shr-parse-image-data))) 951 (let ((data (shr-parse-image-data)))
@@ -998,7 +999,7 @@ element is the data blob and the second element is the content-type."
998 (create-image data nil t :ascent 100 999 (create-image data nil t :ascent 100
999 :format content-type)) 1000 :format content-type))
1000 ((eq content-type 'image/svg+xml) 1001 ((eq content-type 'image/svg+xml)
1001 (create-image data 'imagemagick t :ascent 100)) 1002 (create-image data 'svg t :ascent 100))
1002 ((eq size 'full) 1003 ((eq size 'full)
1003 (ignore-errors 1004 (ignore-errors
1004 (shr-rescale-image data content-type 1005 (shr-rescale-image data content-type
diff --git a/lisp/net/tramp-cache.el b/lisp/net/tramp-cache.el
index ac5a9c45bbd..a162ab00a56 100644
--- a/lisp/net/tramp-cache.el
+++ b/lisp/net/tramp-cache.el
@@ -136,7 +136,11 @@ Returns DEFAULT if not set."
136 (tramp-message key 8 "%s %s %s" file property value) 136 (tramp-message key 8 "%s %s %s" file property value)
137 (when (>= tramp-verbose 10) 137 (when (>= tramp-verbose 10)
138 (let* ((var (intern (concat "tramp-cache-get-count-" property))) 138 (let* ((var (intern (concat "tramp-cache-get-count-" property)))
139 (val (or (and (boundp var) (symbol-value var)) 0))) 139 (val (or (bound-and-true-p var)
140 (progn
141 (add-hook 'tramp-cache-unload-hook
142 (lambda () (makunbound var)))
143 0))))
140 (set var (1+ val)))) 144 (set var (1+ val))))
141 value)) 145 value))
142 146
@@ -156,7 +160,11 @@ Returns VALUE."
156 (tramp-message key 8 "%s %s %s" file property value) 160 (tramp-message key 8 "%s %s %s" file property value)
157 (when (>= tramp-verbose 10) 161 (when (>= tramp-verbose 10)
158 (let* ((var (intern (concat "tramp-cache-set-count-" property))) 162 (let* ((var (intern (concat "tramp-cache-set-count-" property)))
159 (val (or (and (boundp var) (symbol-value var)) 0))) 163 (val (or (bound-and-true-p var)
164 (progn
165 (add-hook 'tramp-cache-unload-hook
166 (lambda () (makunbound var)))
167 0))))
160 (set var (1+ val)))) 168 (set var (1+ val))))
161 value)) 169 value))
162 170
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el
index 94518d0d359..4beb6fe5216 100644
--- a/lisp/net/tramp-sh.el
+++ b/lisp/net/tramp-sh.el
@@ -3432,7 +3432,9 @@ the result will be a local, non-Tramp, file name."
3432 `((,(tramp-file-name-regexp) . tramp-vc-file-name-handler)))) 3432 `((,(tramp-file-name-regexp) . tramp-vc-file-name-handler))))
3433 3433
3434 ;; Here we collect only file names, which need an operation. 3434 ;; Here we collect only file names, which need an operation.
3435 (ignore-errors (tramp-run-real-handler 'vc-registered (list file))) 3435 (tramp-with-demoted-errors
3436 v "Error in 1st pass of `vc-registered': %s"
3437 (tramp-run-real-handler 'vc-registered (list file)))
3436 (tramp-message v 10 "\n%s" tramp-vc-registered-file-names) 3438 (tramp-message v 10 "\n%s" tramp-vc-registered-file-names)
3437 3439
3438 ;; Send just one command, in order to fill the cache. 3440 ;; Send just one command, in order to fill the cache.
@@ -3493,7 +3495,8 @@ the result will be a local, non-Tramp, file name."
3493 v vc-hg-program (tramp-get-remote-path v))))) 3495 v vc-hg-program (tramp-get-remote-path v)))))
3494 (setq vc-handled-backends (remq 'Hg vc-handled-backends))) 3496 (setq vc-handled-backends (remq 'Hg vc-handled-backends)))
3495 ;; Run. 3497 ;; Run.
3496 (ignore-errors 3498 (tramp-with-demoted-errors
3499 v "Error in 2nd pass of `vc-registered': %s"
3497 (tramp-run-real-handler 'vc-registered (list file)))))))) 3500 (tramp-run-real-handler 'vc-registered (list file))))))))
3498 3501
3499;;;###tramp-autoload 3502;;;###tramp-autoload
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index 945f81188c8..8d7fbc068b8 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -1641,6 +1641,18 @@ an input event arrives. The other arguments are passed to `tramp-error'."
1641 (when (tramp-file-name-equal-p vec (car tramp-current-connection)) 1641 (when (tramp-file-name-equal-p vec (car tramp-current-connection))
1642 (setcdr tramp-current-connection (current-time))))))) 1642 (setcdr tramp-current-connection (current-time)))))))
1643 1643
1644(defmacro tramp-with-demoted-errors (vec-or-proc format &rest body)
1645 "Execute BODY while redirecting the error message to `tramp-message'.
1646BODY is executed like wrapped by `with-demoted-errors'. FORMAT
1647is a format-string containing a %-sequence meaning to substitute
1648the resulting error message."
1649 (declare (debug (symbolp body))
1650 (indent 2))
1651 (let ((err (make-symbol "err")))
1652 `(condition-case-unless-debug ,err
1653 (progn ,@body)
1654 (error (tramp-message ,vec-or-proc 3 ,format ,err) nil))))
1655
1644(defmacro with-parsed-tramp-file-name (filename var &rest body) 1656(defmacro with-parsed-tramp-file-name (filename var &rest body)
1645 "Parse a Tramp filename and make components available in the body. 1657 "Parse a Tramp filename and make components available in the body.
1646 1658
diff --git a/lisp/net/trampver.el b/lisp/net/trampver.el
index 4be487e1f4f..527630d747c 100644
--- a/lisp/net/trampver.el
+++ b/lisp/net/trampver.el
@@ -7,7 +7,7 @@
7;; Maintainer: Michael Albinus <michael.albinus@gmx.de> 7;; Maintainer: Michael Albinus <michael.albinus@gmx.de>
8;; Keywords: comm, processes 8;; Keywords: comm, processes
9;; Package: tramp 9;; Package: tramp
10;; Version: 2.3.2 10;; Version: 2.3.3-pre
11 11
12;; This file is part of GNU Emacs. 12;; This file is part of GNU Emacs.
13 13
@@ -33,7 +33,7 @@
33;; should be changed only there. 33;; should be changed only there.
34 34
35;;;###tramp-autoload 35;;;###tramp-autoload
36(defconst tramp-version "2.3.2" 36(defconst tramp-version "2.3.3-pre"
37 "This version of Tramp.") 37 "This version of Tramp.")
38 38
39;;;###tramp-autoload 39;;;###tramp-autoload
@@ -55,7 +55,7 @@
55;; Check for Emacs version. 55;; Check for Emacs version.
56(let ((x (if (>= emacs-major-version 24) 56(let ((x (if (>= emacs-major-version 24)
57 "ok" 57 "ok"
58 (format "Tramp 2.3.2 is not fit for %s" 58 (format "Tramp 2.3.3-pre is not fit for %s"
59 (when (string-match "^.*$" (emacs-version)) 59 (when (string-match "^.*$" (emacs-version))
60 (match-string 0 (emacs-version))))))) 60 (match-string 0 (emacs-version)))))))
61 (unless (string-match "\\`ok\\'" x) (error "%s" x))) 61 (unless (string-match "\\`ok\\'" x) (error "%s" x)))
diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el
index 121ba24f090..dec59c58090 100644
--- a/lisp/progmodes/cc-cmds.el
+++ b/lisp/progmodes/cc-cmds.el
@@ -1843,19 +1843,25 @@ with a brace block."
1843 (unless (eq where 'at-header) 1843 (unless (eq where 'at-header)
1844 (c-backward-to-nth-BOF-{ 1 where) 1844 (c-backward-to-nth-BOF-{ 1 where)
1845 (c-beginning-of-decl-1)) 1845 (c-beginning-of-decl-1))
1846 (when (looking-at c-typedef-key)
1847 (goto-char (match-end 0))
1848 (c-forward-syntactic-ws))
1846 1849
1847 ;; Pick out the defun name, according to the type of defun. 1850 ;; Pick out the defun name, according to the type of defun.
1848 (cond 1851 (cond
1849 ;; struct, union, enum, or similar: 1852 ;; struct, union, enum, or similar:
1850 ((and (looking-at c-type-prefix-key) 1853 ((looking-at c-type-prefix-key)
1851 (progn (c-forward-token-2 2) ; over "struct foo " 1854 (let ((key-pos (point)))
1852 (or (eq (char-after) ?\{) 1855 (c-forward-token-2 1) ; over "struct ".
1853 (looking-at c-symbol-key)))) ; "struct foo bar ..." 1856 (cond
1854 (save-match-data (c-forward-token-2)) 1857 ((looking-at c-symbol-key) ; "struct foo { ..."
1855 (when (eq (char-after) ?\{) 1858 (buffer-substring-no-properties key-pos (match-end 0)))
1856 (c-backward-token-2) 1859 ((eq (char-after) ?{) ; "struct { ... } foo"
1857 (looking-at c-symbol-key)) 1860 (when (c-go-list-forward)
1858 (match-string-no-properties 0)) 1861 (c-forward-syntactic-ws)
1862 (when (looking-at c-symbol-key) ; a bit bogus - there might
1863 ; be several identifiers.
1864 (match-string-no-properties 0)))))))
1859 1865
1860 ((looking-at "DEFUN\\s-*(") ;"DEFUN\\_>") think of XEmacs! 1866 ((looking-at "DEFUN\\s-*(") ;"DEFUN\\_>") think of XEmacs!
1861 ;; DEFUN ("file-name-directory", Ffile_name_directory, Sfile_name_directory, ...) ==> Ffile_name_directory 1867 ;; DEFUN ("file-name-directory", Ffile_name_directory, Sfile_name_directory, ...) ==> Ffile_name_directory
@@ -1900,7 +1906,8 @@ with a brace block."
1900 (c-backward-syntactic-ws)) 1906 (c-backward-syntactic-ws))
1901 (setq name-end (point)) 1907 (setq name-end (point))
1902 (c-back-over-compound-identifier) 1908 (c-back-over-compound-identifier)
1903 (buffer-substring-no-properties (point) name-end))))))))) 1909 (and (looking-at c-symbol-start)
1910 (buffer-substring-no-properties (point) name-end))))))))))
1904 1911
1905(defun c-declaration-limits (near) 1912(defun c-declaration-limits (near)
1906 ;; Return a cons of the beginning and end positions of the current 1913 ;; Return a cons of the beginning and end positions of the current
diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el
index eb7bde0f767..ab910ab7dec 100644
--- a/lisp/progmodes/cc-defs.el
+++ b/lisp/progmodes/cc-defs.el
@@ -417,6 +417,17 @@ to it is returned. This function does not modify the point or the mark."
417 ;; Emacs. 417 ;; Emacs.
418 `(setq mark-active ,activate))) 418 `(setq mark-active ,activate)))
419 419
420(defmacro c-set-keymap-parent (map parent)
421 (cond
422 ;; XEmacs
423 ((cc-bytecomp-fboundp 'set-keymap-parents)
424 `(set-keymap-parents ,map ,parent))
425 ;; Emacs
426 ((cc-bytecomp-fboundp 'set-keymap-parent)
427 `(set-keymap-parent ,map ,parent))
428 ;; incompatible
429 (t (error "CC Mode is incompatible with this version of Emacs"))))
430
420(defmacro c-delete-and-extract-region (start end) 431(defmacro c-delete-and-extract-region (start end)
421 "Delete the text between START and END and return it." 432 "Delete the text between START and END and return it."
422 (if (cc-bytecomp-fboundp 'delete-and-extract-region) 433 (if (cc-bytecomp-fboundp 'delete-and-extract-region)
@@ -1266,6 +1277,7 @@ with value CHAR in the region [FROM to)."
1266(def-edebug-spec cc-eval-when-compile (&rest def-form)) 1277(def-edebug-spec cc-eval-when-compile (&rest def-form))
1267(def-edebug-spec c-point t) 1278(def-edebug-spec c-point t)
1268(def-edebug-spec c-set-region-active t) 1279(def-edebug-spec c-set-region-active t)
1280(def-edebug-spec c-set-keymap-parent t)
1269(def-edebug-spec c-safe t) 1281(def-edebug-spec c-safe t)
1270(def-edebug-spec c-save-buffer-state let*) 1282(def-edebug-spec c-save-buffer-state let*)
1271(def-edebug-spec c-tentative-buffer-changes t) 1283(def-edebug-spec c-tentative-buffer-changes t)
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index e880bd39321..59dc96af030 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -6089,7 +6089,8 @@ comment at the start of cc-engine.el for more info."
6089 6089
6090(defsubst c-clear-found-types () 6090(defsubst c-clear-found-types ()
6091 ;; Clears `c-found-types'. 6091 ;; Clears `c-found-types'.
6092 (setq c-found-types (make-vector 53 0))) 6092 (setq c-found-types
6093 (make-hash-table :test #'equal :weakness nil)))
6093 6094
6094(defun c-add-type (from to) 6095(defun c-add-type (from to)
6095 ;; Add the given region as a type in `c-found-types'. If the region 6096 ;; Add the given region as a type in `c-found-types'. If the region
@@ -6103,29 +6104,27 @@ comment at the start of cc-engine.el for more info."
6103 ;; 6104 ;;
6104 ;; This function might do hidden buffer changes. 6105 ;; This function might do hidden buffer changes.
6105 (let ((type (c-syntactic-content from to c-recognize-<>-arglists))) 6106 (let ((type (c-syntactic-content from to c-recognize-<>-arglists)))
6106 (unless (intern-soft type c-found-types) 6107 (unless (gethash type c-found-types)
6107 (unintern (substring type 0 -1) c-found-types) 6108 (remhash (substring type 0 -1) c-found-types)
6108 (intern type c-found-types)))) 6109 (puthash type t c-found-types))))
6109 6110
6110(defun c-unfind-type (name) 6111(defun c-unfind-type (name)
6111 ;; Remove the "NAME" from c-found-types, if present. 6112 ;; Remove the "NAME" from c-found-types, if present.
6112 (unintern name c-found-types)) 6113 (remhash name c-found-types))
6113 6114
6114(defsubst c-check-type (from to) 6115(defsubst c-check-type (from to)
6115 ;; Return non-nil if the given region contains a type in 6116 ;; Return non-nil if the given region contains a type in
6116 ;; `c-found-types'. 6117 ;; `c-found-types'.
6117 ;; 6118 ;;
6118 ;; This function might do hidden buffer changes. 6119 ;; This function might do hidden buffer changes.
6119 (intern-soft (c-syntactic-content from to c-recognize-<>-arglists) 6120 (gethash (c-syntactic-content from to c-recognize-<>-arglists) c-found-types))
6120 c-found-types))
6121 6121
6122(defun c-list-found-types () 6122(defun c-list-found-types ()
6123 ;; Return all the types in `c-found-types' as a sorted list of 6123 ;; Return all the types in `c-found-types' as a sorted list of
6124 ;; strings. 6124 ;; strings.
6125 (let (type-list) 6125 (let (type-list)
6126 (mapatoms (lambda (type) 6126 (maphash (lambda (type _)
6127 (setq type-list (cons (symbol-name type) 6127 (setq type-list (cons type type-list)))
6128 type-list)))
6129 c-found-types) 6128 c-found-types)
6130 (sort type-list 'string-lessp))) 6129 (sort type-list 'string-lessp)))
6131 6130
@@ -7059,6 +7058,7 @@ comment at the start of cc-engine.el for more info."
7059 ;; This function might do hidden buffer changes. 7058 ;; This function might do hidden buffer changes.
7060 7059
7061 (let ((start (point)) 7060 (let ((start (point))
7061 (old-found-types (copy-hash-table c-found-types))
7062 ;; If `c-record-type-identifiers' is set then activate 7062 ;; If `c-record-type-identifiers' is set then activate
7063 ;; recording of any found types that constitute an argument in 7063 ;; recording of any found types that constitute an argument in
7064 ;; the arglist. 7064 ;; the arglist.
@@ -7074,6 +7074,7 @@ comment at the start of cc-engine.el for more info."
7074 (nconc c-record-found-types c-record-type-identifiers))) 7074 (nconc c-record-found-types c-record-type-identifiers)))
7075 t) 7075 t)
7076 7076
7077 (setq c-found-types old-found-types)
7077 (goto-char start) 7078 (goto-char start)
7078 nil))) 7079 nil)))
7079 7080
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index 9b89681c3bf..bf0439ffe8a 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -225,18 +225,7 @@ control). See \"cc-mode.el\" for more info."
225 225
226(defun c-make-inherited-keymap () 226(defun c-make-inherited-keymap ()
227 (let ((map (make-sparse-keymap))) 227 (let ((map (make-sparse-keymap)))
228 ;; Necessary to use `cc-bytecomp-fboundp' below since this 228 (c-set-keymap-parent map c-mode-base-map)
229 ;; function is called from top-level forms that are evaluated
230 ;; while cc-bytecomp is active when one does M-x eval-buffer.
231 (cond
232 ;; Emacs
233 ((cc-bytecomp-fboundp 'set-keymap-parent)
234 (set-keymap-parent map c-mode-base-map))
235 ;; XEmacs
236 ((fboundp 'set-keymap-parents)
237 (set-keymap-parents map c-mode-base-map))
238 ;; incompatible
239 (t (error "CC Mode is incompatible with this version of Emacs")))
240 map)) 229 map))
241 230
242(defun c-define-abbrev-table (name defs &optional doc) 231(defun c-define-abbrev-table (name defs &optional doc)
@@ -276,6 +265,8 @@ control). See \"cc-mode.el\" for more info."
276 nil 265 nil
277 266
278 (setq c-mode-base-map (make-sparse-keymap)) 267 (setq c-mode-base-map (make-sparse-keymap))
268 (when (boundp 'prog-mode-map)
269 (c-set-keymap-parent c-mode-base-map prog-mode-map))
279 270
280 ;; Separate M-BS from C-M-h. The former should remain 271 ;; Separate M-BS from C-M-h. The former should remain
281 ;; backward-kill-word. 272 ;; backward-kill-word.
@@ -446,27 +437,36 @@ preferably use the `c-mode-menu' language constant directly."
446 t)))) 437 t))))
447 438
448(defun c-unfind-coalesced-tokens (beg end) 439(defun c-unfind-coalesced-tokens (beg end)
449 ;; unless the non-empty region (beg end) is entirely WS and there's at 440 ;; If removing the region (beg end) would coalesce an identifier ending at
450 ;; least one character of WS just before or after this region, remove 441 ;; beg with an identifier (fragment) beginning at end, or an identifier
451 ;; the tokens which touch the region from `c-found-types' should they 442 ;; fragment ending at beg with an identifier beginning at end, remove the
452 ;; be present. 443 ;; pertinent identifier(s) from `c-found-types'.
453 (or (c-partial-ws-p beg end) 444 (save-excursion
454 (save-excursion 445 (when (< beg end)
455 (progn 446 (goto-char beg)
456 (goto-char beg) 447 (when
457 (or (eq beg (point-min)) 448 (and (not (bobp))
458 (c-skip-ws-backward (1- beg)) 449 (progn (c-backward-syntactic-ws) (eq (point) beg))
459 (/= (point) beg) 450 (/= (skip-chars-backward c-symbol-chars (1- (point))) 0)
460 (= (c-backward-token-2) 1) 451 (progn (goto-char beg) (c-forward-syntactic-ws) (<= (point) end))
461 (c-unfind-type (buffer-substring-no-properties 452 (> (point) beg)
462 (point) beg))) 453 (goto-char end)
463 (goto-char end) 454 (looking-at c-symbol-char-key))
464 (or (eq end (point-max)) 455 (goto-char beg)
465 (c-skip-ws-forward (1+ end)) 456 (c-simple-skip-symbol-backward)
466 (/= (point) end) 457 (c-unfind-type (buffer-substring-no-properties (point) beg)))
467 (progn (forward-char) (c-end-of-current-token) nil) 458
468 (c-unfind-type (buffer-substring-no-properties 459 (goto-char end)
469 end (point)))))))) 460 (when
461 (and (not (eobp))
462 (progn (c-forward-syntactic-ws) (eq (point) end))
463 (looking-at c-symbol-char-key)
464 (progn (c-backward-syntactic-ws) (>= (point) beg))
465 (< (point) end)
466 (/= (skip-chars-backward c-symbol-chars (1- (point))) 0))
467 (goto-char (1+ end))
468 (c-end-of-current-token)
469 (c-unfind-type (buffer-substring-no-properties end (point)))))))
470 470
471;; c-maybe-stale-found-type records a place near the region being 471;; c-maybe-stale-found-type records a place near the region being
472;; changed where an element of `found-types' might become stale. It 472;; changed where an element of `found-types' might become stale. It
diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el
index c0f1aaf39d4..c69eca22413 100644
--- a/lisp/progmodes/cperl-mode.el
+++ b/lisp/progmodes/cperl-mode.el
@@ -3734,7 +3734,7 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
3734 "\\(\\`\n?\\|^\n\\)=" ; POD 3734 "\\(\\`\n?\\|^\n\\)=" ; POD
3735 "\\|" 3735 "\\|"
3736 ;; One extra () before this: 3736 ;; One extra () before this:
3737 "<<" ; HERE-DOC 3737 "<<~?" ; HERE-DOC
3738 "\\(" ; 1 + 1 3738 "\\(" ; 1 + 1
3739 ;; First variant "BLAH" or just ``. 3739 ;; First variant "BLAH" or just ``.
3740 "[ \t]*" ; Yes, whitespace is allowed! 3740 "[ \t]*" ; Yes, whitespace is allowed!
@@ -4000,7 +4000,7 @@ the sections using `cperl-pod-head-face', `cperl-pod-face',
4000 (setq b (point)) 4000 (setq b (point))
4001 ;; We do not search to max, since we may be called from 4001 ;; We do not search to max, since we may be called from
4002 ;; some hook of fontification, and max is random 4002 ;; some hook of fontification, and max is random
4003 (or (and (re-search-forward (concat "^" qtag "$") 4003 (or (and (re-search-forward (concat "^[ \t]*" qtag "$")
4004 stop-point 'toend) 4004 stop-point 'toend)
4005 ;;;(eq (following-char) ?\n) ; XXXX WHY??? 4005 ;;;(eq (following-char) ?\n) ; XXXX WHY???
4006 ) 4006 )
diff --git a/lisp/progmodes/executable.el b/lisp/progmodes/executable.el
index da148bd39aa..7c040e74955 100644
--- a/lisp/progmodes/executable.el
+++ b/lisp/progmodes/executable.el
@@ -83,13 +83,21 @@ When this is `function', only ask when called non-interactively."
83 :type 'regexp 83 :type 'regexp
84 :group 'executable) 84 :group 'executable)
85 85
86
87(defcustom executable-prefix "#!" 86(defcustom executable-prefix "#!"
88 "Interpreter magic number prefix inserted when there was no magic number." 87 "Interpreter magic number prefix inserted when there was no magic number.
89 :version "24.3" ; "#! " -> "#!" 88Use of `executable-prefix-env' is preferable to this option."
89 :version "26.1" ; deprecated
90 :type 'string 90 :type 'string
91 :group 'executable) 91 :group 'executable)
92 92
93(defcustom executable-prefix-env nil
94 "If non-nil, use \"/usr/bin/env\" in interpreter magic number.
95If this variable is non-nil, the interpreter magic number inserted
96by `executable-set-magic' will be \"#!/usr/bin/env INTERPRETER\",
97otherwise it will be \"#!/path/to/INTERPRETER\"."
98 :version "26.1"
99 :type 'boolean
100 :group 'executable)
93 101
94(defcustom executable-chmod 73 102(defcustom executable-chmod 73
95 "After saving, if the file is not executable, set this mode. 103 "After saving, if the file is not executable, set this mode.
@@ -199,7 +207,7 @@ command to find the next error. The buffer is also in `comint-mode' and
199(defun executable-set-magic (interpreter &optional argument 207(defun executable-set-magic (interpreter &optional argument
200 no-query-flag insert-flag) 208 no-query-flag insert-flag)
201 "Set this buffer's interpreter to INTERPRETER with optional ARGUMENT. 209 "Set this buffer's interpreter to INTERPRETER with optional ARGUMENT.
202The variables `executable-magicless-file-regexp', `executable-prefix', 210The variables `executable-magicless-file-regexp', `executable-prefix-env',
203`executable-insert', `executable-query' and `executable-chmod' control 211`executable-insert', `executable-query' and `executable-chmod' control
204when and how magic numbers are inserted or replaced and scripts made 212when and how magic numbers are inserted or replaced and scripts made
205executable." 213executable."
@@ -220,6 +228,14 @@ executable."
220 (and argument (string< "" argument) " ") 228 (and argument (string< "" argument) " ")
221 argument)) 229 argument))
222 230
231 ;; For backward compatibilty, allow `executable-prefix-env' to be
232 ;; overriden by custom `executable-prefix'.
233 (if (string-match "#!\\([ \t]*/usr/bin/env[ \t]*\\)?$" executable-prefix)
234 (if executable-prefix-env
235 (setq argument (concat "/usr/bin/env "
236 (file-name-nondirectory argument))))
237 (setq argument (concat (substring executable-prefix 2) argument)))
238
223 (or buffer-read-only 239 (or buffer-read-only
224 (if buffer-file-name 240 (if buffer-file-name
225 (string-match executable-magicless-file-regexp 241 (string-match executable-magicless-file-regexp
@@ -241,15 +257,13 @@ executable."
241 ;; Make buffer visible before question. 257 ;; Make buffer visible before question.
242 (switch-to-buffer (current-buffer)) 258 (switch-to-buffer (current-buffer))
243 (y-or-n-p (format-message 259 (y-or-n-p (format-message
244 "Replace magic number by `%s%s'? " 260 "Replace magic number by `#!%s'? "
245 executable-prefix argument)))) 261 argument))))
246 (progn 262 (progn
247 (replace-match argument t t nil 1) 263 (replace-match argument t t nil 1)
248 (message "Magic number changed to `%s'" 264 (message "Magic number changed to `#!%s'" argument))))
249 (concat executable-prefix argument))))) 265 (insert "#!" argument ?\n)
250 (insert executable-prefix argument ?\n) 266 (message "Magic number changed to `#!%s'" argument))))
251 (message "Magic number changed to `%s'"
252 (concat executable-prefix argument)))))
253 interpreter) 267 interpreter)
254 268
255 269
diff --git a/lisp/progmodes/grep.el b/lisp/progmodes/grep.el
index b3d8a51ceeb..2ddaf884bce 100644
--- a/lisp/progmodes/grep.el
+++ b/lisp/progmodes/grep.el
@@ -47,8 +47,8 @@ to avoid computing them again.")
47(defun grep-apply-setting (symbol value) 47(defun grep-apply-setting (symbol value)
48 "Set SYMBOL to VALUE, and update `grep-host-defaults-alist'. 48 "Set SYMBOL to VALUE, and update `grep-host-defaults-alist'.
49SYMBOL should be one of `grep-command', `grep-template', 49SYMBOL should be one of `grep-command', `grep-template',
50`grep-use-null-device', `grep-find-command', 50`grep-use-null-device', `grep-find-command' `grep-find-template',
51`grep-find-template', `grep-find-use-xargs', or 51`grep-find-use-xargs', `grep-use-null-filename-separator', or
52`grep-highlight-matches'." 52`grep-highlight-matches'."
53 (when grep-host-defaults-alist 53 (when grep-host-defaults-alist
54 (let* ((host-id 54 (let* ((host-id
@@ -160,6 +160,15 @@ Customize or call the function `grep-apply-setting'."
160 :set 'grep-apply-setting 160 :set 'grep-apply-setting
161 :group 'grep) 161 :group 'grep)
162 162
163(defcustom grep-use-null-filename-separator 'auto-detect
164 "If non-nil, use `grep's `--null' option.
165This is done to disambiguate file names in `grep's output."
166 :type '(choice (const :tag "Do Not Use `--null'" nil)
167 (const :tag "Use `--null'" t)
168 (other :tag "Not Set" auto-detect))
169 :set 'grep-apply-setting
170 :group 'grep)
171
163;;;###autoload 172;;;###autoload
164(defcustom grep-find-command nil 173(defcustom grep-find-command nil
165 "The default find command for \\[grep-find]. 174 "The default find command for \\[grep-find].
@@ -357,33 +366,53 @@ A grep buffer becomes most recent when you select Grep mode in it.
357Notice that using \\[next-error] or \\[compile-goto-error] modifies 366Notice that using \\[next-error] or \\[compile-goto-error] modifies
358`compilation-last-buffer' rather than `grep-last-buffer'.") 367`compilation-last-buffer' rather than `grep-last-buffer'.")
359 368
360;;;###autoload 369(defconst grep--regexp-alist-column
361(defconst grep-regexp-alist 370 ;; Calculate column positions (col . end-col) of first grep match on a line
362 '( 371 (cons
363 ;; Use a tight regexp to handle weird file names (with colons 372 (lambda ()
373 (when grep-highlight-matches
374 (let* ((beg (match-end 0))
375 (end (save-excursion (goto-char beg) (line-end-position)))
376 (mbeg (text-property-any beg end 'font-lock-face 'grep-match-face)))
377 (when mbeg
378 (- mbeg beg)))))
379 (lambda ()
380 (when grep-highlight-matches
381 (let* ((beg (match-end 0))
382 (end (save-excursion (goto-char beg) (line-end-position)))
383 (mbeg (text-property-any beg end 'font-lock-face 'grep-match-face))
384 (mend (and mbeg (next-single-property-change mbeg 'font-lock-face nil end))))
385 (when mend
386 (- mend beg)))))))
387(defconst grep--regexp-alist-bin-matcher
388 '("^Binary file \\(.+\\) matches$" 1 nil nil 0 1))
389(defconst grep-with-null-regexp-alist
390 `(("^\\([^\0]+\\)\\(\0\\)\\([0-9]+\\):" 1 3 ,grep--regexp-alist-column nil nil
391 (2 '(face unspecified display ":")))
392 ,grep--regexp-alist-bin-matcher)
393 "Regexp used to match grep hits.
394See `compilation-error-regexp-alist'.")
395(defconst grep-fallback-regexp-alist
396 `(;; Use a tight regexp to handle weird file names (with colons
364 ;; in them) as well as possible. E.g., use [1-9][0-9]* rather 397 ;; in them) as well as possible. E.g., use [1-9][0-9]* rather
365 ;; than [0-9]+ so as to accept ":034:" in file names. 398 ;; than [0-9]+ so as to accept ":034:" in file names.
366 ("^\\(.*?[^/\n]\\):[ \t]*\\([1-9][0-9]*\\)[ \t]*:" 399 ("^\\(.*?[^/\n]\\):[ \t]*\\([1-9][0-9]*\\)[ \t]*:"
367 1 2 400 1 2 ,grep--regexp-alist-column)
368 ;; Calculate column positions (col . end-col) of first grep match on a line 401 ,grep--regexp-alist-bin-matcher)
369 ((lambda () 402 "Regexp used to match grep hits when `--null' is not supported.
370 (when grep-highlight-matches 403See `compilation-error-regexp-alist'.")
371 (let* ((beg (match-end 0)) 404
372 (end (save-excursion (goto-char beg) (line-end-position))) 405(defvaralias 'grep-regex-alist 'grep-with-null-regexp-alist)
373 (mbeg (text-property-any beg end 'font-lock-face grep-match-face))) 406(make-obsolete-variable
374 (when mbeg 407 'grep-regex-alist "Call `grep-regexp-alist' instead." "26.1")
375 (- mbeg beg))))) 408
376 . 409;;;###autoload
377 (lambda () 410(defun grep-regexp-alist ()
378 (when grep-highlight-matches 411 "Return a regexp alist to match grep hits.
379 (let* ((beg (match-end 0)) 412The regexp used depends on `grep-use-null-filename-separator'.
380 (end (save-excursion (goto-char beg) (line-end-position))) 413See `compilation-error-regexp-alist' for format details."
381 (mbeg (text-property-any beg end 'font-lock-face grep-match-face)) 414 (if grep-use-null-filename-separator
382 (mend (and mbeg (next-single-property-change mbeg 'font-lock-face nil end)))) 415 grep-with-null-regexp-alist grep-fallback-regexp-alist))
383 (when mend
384 (- mend beg)))))))
385 ("^Binary file \\(.+\\) matches$" 1 nil nil 0 1))
386 "Regexp used to match grep hits. See `compilation-error-regexp-alist'.")
387 416
388(defvar grep-first-column 0 ; bug#10594 417(defvar grep-first-column 0 ; bug#10594
389 "Value to use for `compilation-first-column' in grep buffers.") 418 "Value to use for `compilation-first-column' in grep buffers.")
@@ -538,6 +567,8 @@ This function is called from `compilation-filter-hook'."
538 (grep-use-null-device ,grep-use-null-device) 567 (grep-use-null-device ,grep-use-null-device)
539 (grep-find-command ,grep-find-command) 568 (grep-find-command ,grep-find-command)
540 (grep-find-template ,grep-find-template) 569 (grep-find-template ,grep-find-template)
570 (grep-use-null-filename-separator
571 ,grep-use-null-filename-separator)
541 (grep-find-use-xargs ,grep-find-use-xargs) 572 (grep-find-use-xargs ,grep-find-use-xargs)
542 (grep-highlight-matches ,grep-highlight-matches))))) 573 (grep-highlight-matches ,grep-highlight-matches)))))
543 (let* ((host-id 574 (let* ((host-id
@@ -550,7 +581,8 @@ This function is called from `compilation-filter-hook'."
550 ;; computed for every host once. 581 ;; computed for every host once.
551 (dolist (setting '(grep-command grep-template 582 (dolist (setting '(grep-command grep-template
552 grep-use-null-device grep-find-command 583 grep-use-null-device grep-find-command
553 grep-find-template grep-find-use-xargs 584 grep-use-null-filename-separator
585 grep-find-template grep-find-use-xargs
554 grep-highlight-matches)) 586 grep-highlight-matches))
555 (set setting 587 (set setting
556 (cadr (or (assq setting host-defaults) 588 (cadr (or (assq setting host-defaults)
@@ -576,6 +608,21 @@ This function is called from `compilation-filter-hook'."
576 (concat (regexp-quote hello-file) 608 (concat (regexp-quote hello-file)
577 ":[0-9]+:English"))))))))) 609 ":[0-9]+:English")))))))))
578 610
611 (when (eq grep-use-null-filename-separator 'auto-detect)
612 (setq grep-use-null-filename-separator
613 (with-temp-buffer
614 (let* ((hello-file (expand-file-name "HELLO" data-directory))
615 (args `("--null" "-ne" "^English" ,hello-file)))
616 (if grep-use-null-device
617 (setq args (append args (list null-device)))
618 (push "-H" args))
619 (and (grep-probe grep-program `(nil t nil ,@args))
620 (progn
621 (goto-char (point-min))
622 (looking-at
623 (concat (regexp-quote hello-file)
624 "\0[0-9]+:English"))))))))
625
579 (when (eq grep-highlight-matches 'auto-detect) 626 (when (eq grep-highlight-matches 'auto-detect)
580 (setq grep-highlight-matches 627 (setq grep-highlight-matches
581 (with-temp-buffer 628 (with-temp-buffer
@@ -591,6 +638,7 @@ This function is called from `compilation-filter-hook'."
591 grep-template grep-find-template) 638 grep-template grep-find-template)
592 (let ((grep-options 639 (let ((grep-options
593 (concat (if grep-use-null-device "-n" "-nH") 640 (concat (if grep-use-null-device "-n" "-nH")
641 (if grep-use-null-filename-separator " --null")
594 (if (grep-probe grep-program 642 (if (grep-probe grep-program
595 `(nil nil nil "-e" "foo" ,null-device) 643 `(nil nil nil "-e" "foo" ,null-device)
596 nil 1) 644 nil 1)
@@ -733,7 +781,7 @@ This function is called from `compilation-filter-hook'."
733 (set (make-local-variable 'compilation-error-face) 781 (set (make-local-variable 'compilation-error-face)
734 grep-hit-face) 782 grep-hit-face)
735 (set (make-local-variable 'compilation-error-regexp-alist) 783 (set (make-local-variable 'compilation-error-regexp-alist)
736 grep-regexp-alist) 784 (grep-regexp-alist))
737 ;; compilation-directory-matcher can't be nil, so we set it to a regexp that 785 ;; compilation-directory-matcher can't be nil, so we set it to a regexp that
738 ;; can never match. 786 ;; can never match.
739 (set (make-local-variable 'compilation-directory-matcher) '("\\`a\\`")) 787 (set (make-local-variable 'compilation-directory-matcher) '("\\`a\\`"))
diff --git a/lisp/progmodes/ld-script.el b/lisp/progmodes/ld-script.el
index 389ddfca6b1..7a666e95297 100644
--- a/lisp/progmodes/ld-script.el
+++ b/lisp/progmodes/ld-script.el
@@ -85,10 +85,12 @@
85 ;; 3.4.5 Other Linker Script Commands 85 ;; 3.4.5 Other Linker Script Commands
86 "ASSERT" "EXTERN" "FORCE_COMMON_ALLOCATION" 86 "ASSERT" "EXTERN" "FORCE_COMMON_ALLOCATION"
87 "INHIBIT_COMMON_ALLOCATION" "INSERT" "AFTER" "BEFORE" 87 "INHIBIT_COMMON_ALLOCATION" "INSERT" "AFTER" "BEFORE"
88 "NOCROSSREFS" "OUTPUT_ARCH" "LD_FEATURE" 88 "NOCROSSREFS" "NOCROSSREFS_TO" "OUTPUT_ARCH" "LD_FEATURE"
89 ;; 3.5.2 PROVIDE 89 ;; 3.5.2 HIDDEN
90 "HIDDEN"
91 ;; 3.5.3 PROVIDE
90 "PROVIDE" 92 "PROVIDE"
91 ;; 3.5.3 PROVIDE_HIDDEN 93 ;; 3.5.4 PROVIDE_HIDDEN
92 "PROVIDE_HIDDEN" 94 "PROVIDE_HIDDEN"
93 ;; 3.6 SECTIONS Command 95 ;; 3.6 SECTIONS Command
94 "SECTIONS" 96 "SECTIONS"
@@ -142,6 +144,7 @@
142 "DEFINED" 144 "DEFINED"
143 "LENGTH" "len" "l" 145 "LENGTH" "len" "l"
144 "LOADADDR" 146 "LOADADDR"
147 "LOG2CEIL"
145 "MAX" 148 "MAX"
146 "MIN" 149 "MIN"
147 "NEXT" 150 "NEXT"
diff --git a/lisp/progmodes/perl-mode.el b/lisp/progmodes/perl-mode.el
index 3def37a2ea8..6197a53ee66 100644
--- a/lisp/progmodes/perl-mode.el
+++ b/lisp/progmodes/perl-mode.el
@@ -213,25 +213,6 @@
213 (regexp-opt perl--syntax-exp-intro-keywords) 213 (regexp-opt perl--syntax-exp-intro-keywords)
214 "\\|[-?:.,;|&+*=!~({[]\\|\\(^\\)\\)[ \t\n]*"))) 214 "\\|[-?:.,;|&+*=!~({[]\\|\\(^\\)\\)[ \t\n]*")))
215 215
216;; FIXME: handle here-docs and regexps.
217;; <<EOF <<"EOF" <<'EOF' (no space)
218;; see `man perlop'
219;; ?...?
220;; /.../
221;; m [...]
222;; m /.../
223;; q /.../ = '...'
224;; qq /.../ = "..."
225;; qx /.../ = `...`
226;; qr /.../ = precompiled regexp =~=~ m/.../
227;; qw /.../
228;; s /.../.../
229;; s <...> /.../
230;; s '...'...'
231;; tr /.../.../
232;; y /.../.../
233;;
234;; <file*glob>
235(defun perl-syntax-propertize-function (start end) 216(defun perl-syntax-propertize-function (start end)
236 (let ((case-fold-search nil)) 217 (let ((case-fold-search nil))
237 (goto-char start) 218 (goto-char start)
@@ -324,23 +305,25 @@
324 ((concat 305 ((concat
325 "\\(?:" 306 "\\(?:"
326 ;; << "EOF", << 'EOF', or << \EOF 307 ;; << "EOF", << 'EOF', or << \EOF
327 "<<[ \t]*\\('[^'\n]*'\\|\"[^\"\n]*\"\\|\\\\[[:alpha:]][[:alnum:]]*\\)" 308 "<<\\(~\\)?[ \t]*\\('[^'\n]*'\\|\"[^\"\n]*\"\\|\\\\[[:alpha:]][[:alnum:]]*\\)"
328 ;; The <<EOF case which needs perl--syntax-exp-intro-regexp, to 309 ;; The <<EOF case which needs perl--syntax-exp-intro-regexp, to
329 ;; disambiguate with the left-bitshift operator. 310 ;; disambiguate with the left-bitshift operator.
330 "\\|" perl--syntax-exp-intro-regexp "<<\\(?1:\\sw+\\)\\)" 311 "\\|" perl--syntax-exp-intro-regexp "<<\\(?2:\\sw+\\)\\)"
331 ".*\\(\n\\)") 312 ".*\\(\n\\)")
332 (3 (let* ((st (get-text-property (match-beginning 3) 'syntax-table)) 313 (4 (let* ((st (get-text-property (match-beginning 4) 'syntax-table))
333 (name (match-string 1))) 314 (name (match-string 2))
334 (goto-char (match-end 1)) 315 (indented (match-beginning 1)))
316 (goto-char (match-end 2))
335 (if (save-excursion (nth 8 (syntax-ppss (match-beginning 0)))) 317 (if (save-excursion (nth 8 (syntax-ppss (match-beginning 0))))
336 ;; Leave the property of the newline unchanged. 318 ;; Leave the property of the newline unchanged.
337 st 319 st
338 (cons (car (string-to-syntax "< c")) 320 (cons (car (string-to-syntax "< c"))
339 ;; Remember the names of heredocs found on this line. 321 ;; Remember the names of heredocs found on this line.
340 (cons (pcase (aref name 0) 322 (cons (cons (pcase (aref name 0)
341 (`?\\ (substring name 1)) 323 (`?\\ (substring name 1))
342 ((or `?\" `?\' `?\`) (substring name 1 -1)) 324 ((or `?\" `?\' `?\`) (substring name 1 -1))
343 (_ name)) 325 (_ name))
326 indented)
344 (cdr st))))))) 327 (cdr st)))))))
345 ;; We don't call perl-syntax-propertize-special-constructs directly 328 ;; We don't call perl-syntax-propertize-special-constructs directly
346 ;; from the << rule, because there might be other elements (between 329 ;; from the << rule, because there might be other elements (between
@@ -383,7 +366,9 @@
383 (goto-char (nth 8 state))) 366 (goto-char (nth 8 state)))
384 (while (and names 367 (while (and names
385 (re-search-forward 368 (re-search-forward
386 (concat "^" (regexp-quote (pop names)) "\n") 369 (pcase-let ((`(,name . ,indented) (pop names)))
370 (concat "^" (if indented "[ \t]*")
371 (regexp-quote name) "\n"))
387 limit 'move)) 372 limit 'move))
388 (unless names 373 (unless names
389 (put-text-property (1- (point)) (point) 'syntax-table 374 (put-text-property (1- (point)) (point) 'syntax-table
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index b8ec50f14ae..cc9b794c5a0 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -917,20 +917,21 @@ IGNORES is a list of glob patterns."
917 (grep-compute-defaults) 917 (grep-compute-defaults)
918 (defvar grep-find-template) 918 (defvar grep-find-template)
919 (defvar grep-highlight-matches) 919 (defvar grep-highlight-matches)
920 (let* ((grep-find-template (replace-regexp-in-string "<C>" "<C> -E" 920 (pcase-let*
921 grep-find-template t t)) 921 ((grep-find-template (replace-regexp-in-string "<C>" "<C> -E"
922 (grep-highlight-matches nil) 922 grep-find-template t t))
923 ;; TODO: Sanitize the regexp to remove Emacs-specific terms, 923 (grep-highlight-matches nil)
924 ;; so that Grep can search for the "relaxed" version. Can we 924 ;; TODO: Sanitize the regexp to remove Emacs-specific terms,
925 ;; do that reliably enough, without creating false negatives? 925 ;; so that Grep can search for the "relaxed" version. Can we
926 (command (xref--rgrep-command (xref--regexp-to-extended regexp) 926 ;; do that reliably enough, without creating false negatives?
927 files 927 (command (xref--rgrep-command (xref--regexp-to-extended regexp)
928 (expand-file-name dir) 928 files
929 ignores)) 929 (expand-file-name dir)
930 (buf (get-buffer-create " *xref-grep*")) 930 ignores))
931 (grep-re (caar grep-regexp-alist)) 931 (buf (get-buffer-create " *xref-grep*"))
932 status 932 (`(,grep-re ,file-group ,line-group . ,_) (car (grep-regexp-alist)))
933 hits) 933 (status nil)
934 (hits nil))
934 (with-current-buffer buf 935 (with-current-buffer buf
935 (erase-buffer) 936 (erase-buffer)
936 (setq status 937 (setq status
@@ -944,8 +945,8 @@ IGNORES is a list of glob patterns."
944 (not (looking-at grep-re))) 945 (not (looking-at grep-re)))
945 (user-error "Search failed with status %d: %s" status (buffer-string))) 946 (user-error "Search failed with status %d: %s" status (buffer-string)))
946 (while (re-search-forward grep-re nil t) 947 (while (re-search-forward grep-re nil t)
947 (push (list (string-to-number (match-string 2)) 948 (push (list (string-to-number (match-string line-group))
948 (match-string 1) 949 (match-string file-group)
949 (buffer-substring-no-properties (point) (line-end-position))) 950 (buffer-substring-no-properties (point) (line-end-position)))
950 hits))) 951 hits)))
951 (xref--convert-hits (nreverse hits) regexp))) 952 (xref--convert-hits (nreverse hits) regexp)))
diff --git a/lisp/ses.el b/lisp/ses.el
index 741d588e4be..8c5ff2136f9 100644
--- a/lisp/ses.el
+++ b/lisp/ses.el
@@ -167,12 +167,32 @@ Each function is called with ARG=1."
167 ["Export values" ses-export-tsv t] 167 ["Export values" ses-export-tsv t]
168 ["Export formulas" ses-export-tsf t])) 168 ["Export formulas" ses-export-tsf t]))
169 169
170(defconst ses-completion-keys '("\M-\C-i" "\C-i")
171 "List for keys that can be used for completion while editing.")
172
173(defvar ses--completion-table nil
174 "Set globally to what completion table to use depending on type
175 of completion (local printers, cells, etc.). We need to go
176 through a local variable to pass the SES buffer local variable
177 to completing function while the current buffer is the
178 minibuffer.")
179
180(defvar ses--list-orig-buffer nil
181 "Calling buffer for SES listing help. Used for listing local
182 printers or renamed cells.")
183
184
170(defconst ses-mode-edit-map 185(defconst ses-mode-edit-map
171 (let ((keys '("\C-c\C-r" ses-insert-range 186 (let ((keys '("\C-c\C-r" ses-insert-range
172 "\C-c\C-s" ses-insert-ses-range 187 "\C-c\C-s" ses-insert-ses-range
173 [S-mouse-3] ses-insert-range-click 188 [S-mouse-3] ses-insert-range-click
174 [C-S-mouse-3] ses-insert-ses-range-click 189 [C-S-mouse-3] ses-insert-ses-range-click
175 "\M-\C-i" lisp-complete-symbol)) ; FIXME obsolete 190 "\C-h\C-p" ses-list-local-printers
191 "\C-h\C-n" ses-list-named-cells
192 "\M-\C-i" lisp-complete-symbol)) ; redefined
193 ; dynamically in
194 ; editing
195 ; functions
176 (newmap (make-sparse-keymap))) 196 (newmap (make-sparse-keymap)))
177 (set-keymap-parent newmap minibuffer-local-map) 197 (set-keymap-parent newmap minibuffer-local-map)
178 (while keys 198 (while keys
@@ -1715,7 +1735,7 @@ to each symbol."
1715 (set (make-local-variable sym) nil) 1735 (set (make-local-variable sym) nil)
1716 (put sym 'ses-cell (cons row col)))))) ))) 1736 (put sym 'ses-cell (cons row col)))))) )))
1717 ;; Relocate the cell values. 1737 ;; Relocate the cell values.
1718 (let (oldval myrow mycol xrow xcol) 1738 (let (oldval myrow mycol xrow xcol sym)
1719 (cond 1739 (cond
1720 ((and (<= rowincr 0) (<= colincr 0)) 1740 ((and (<= rowincr 0) (<= colincr 0))
1721 ;; Deletion of rows and/or columns. 1741 ;; Deletion of rows and/or columns.
@@ -1725,16 +1745,16 @@ to each symbol."
1725 (dotimes (col (- ses--numcols mincol)) 1745 (dotimes (col (- ses--numcols mincol))
1726 (setq mycol (+ col mincol) 1746 (setq mycol (+ col mincol)
1727 xrow (- myrow rowincr) 1747 xrow (- myrow rowincr)
1728 xcol (- mycol colincr)) 1748 xcol (- mycol colincr)
1729 (let ((sym (ses-cell-symbol myrow mycol))) 1749 sym (ses-cell-symbol myrow mycol))
1730 ;; We don't need to relocate value for renamed cells, as they keep the same 1750 ;; We don't need to relocate value for renamed cells, as they keep the same
1731 ;; symbol. 1751 ;; symbol.
1732 (unless (eq (get sym 'ses-cell) :ses-named) 1752 (unless (eq (get sym 'ses-cell) :ses-named)
1733 (ses-set-cell myrow mycol 'value 1753 (ses-set-cell myrow mycol 'value
1734 (if (and (< xrow ses--numrows) (< xcol ses--numcols)) 1754 (if (and (< xrow ses--numrows) (< xcol ses--numcols))
1735 (ses-cell-value xrow xcol) 1755 (ses-cell-value xrow xcol)
1736 ;; Cell is off the end of the array. 1756 ;; Cell is off the end of the array.
1737 (symbol-value (ses-create-cell-symbol xrow xcol)))))))) 1757 (symbol-value (ses-create-cell-symbol xrow xcol)))))))
1738 (when ses--in-killing-named-cell-list 1758 (when ses--in-killing-named-cell-list
1739 (message "Unbinding killed named cell symbols...") 1759 (message "Unbinding killed named cell symbols...")
1740 (setq ses-start-time (float-time)) 1760 (setq ses-start-time (float-time))
@@ -1754,13 +1774,17 @@ to each symbol."
1754 (dotimes (col (- ses--numcols mincol)) 1774 (dotimes (col (- ses--numcols mincol))
1755 (setq mycol (- distx col) 1775 (setq mycol (- distx col)
1756 xrow (- myrow rowincr) 1776 xrow (- myrow rowincr)
1757 xcol (- mycol colincr)) 1777 xcol (- mycol colincr)
1758 (if (or (< xrow minrow) (< xcol mincol)) 1778 sym (ses-cell-symbol myrow mycol))
1759 ;; Newly-inserted value. 1779 ;; We don't need to relocate value for renamed cells, as they keep the same
1760 (setq oldval nil) 1780 ;; symbol.
1761 ;; Transfer old value. 1781 (unless (eq (get sym 'ses-cell) :ses-named)
1762 (setq oldval (ses-cell-value xrow xcol))) 1782 (if (or (< xrow minrow) (< xcol mincol))
1763 (ses-set-cell myrow mycol 'value oldval))) 1783 ;; Newly-inserted value.
1784 (setq oldval nil)
1785 ;; Transfer old value.
1786 (setq oldval (ses-cell-value xrow xcol)))
1787 (ses-set-cell myrow mycol 'value oldval))))
1764 t)) ; Make testcover happy by returning non-nil here. 1788 t)) ; Make testcover happy by returning non-nil here.
1765 (t 1789 (t
1766 (error "ROWINCR and COLINCR must have the same sign")))) 1790 (error "ROWINCR and COLINCR must have the same sign"))))
@@ -2443,6 +2467,42 @@ to are recalculated first."
2443;;---------------------------------------------------------------------------- 2467;;----------------------------------------------------------------------------
2444;; Input of cell formulas 2468;; Input of cell formulas
2445;;---------------------------------------------------------------------------- 2469;;----------------------------------------------------------------------------
2470(defun ses-edit-cell-complete-symbol ()
2471 (interactive)
2472 (let ((completion-at-point-functions (cons 'ses--edit-cell-completion-at-point-function
2473 completion-at-point-functions)))
2474 (completion-at-point)))
2475
2476(defun ses--edit-cell-completion-at-point-function ()
2477 (and
2478 ses--completion-table
2479 (let* ((bol (save-excursion (move-beginning-of-line nil) (point)))
2480 start end collection
2481 (prefix
2482 (save-excursion
2483 (setq end (point))
2484 (backward-sexp)
2485 (if (< (point) bol)
2486 (progn
2487 (setq start bol)
2488 (buffer-substring start end))
2489 (setq start (point))
2490 (forward-sexp)
2491 (if (>= (point) end)
2492 (progn
2493 (setq end (point))
2494 (buffer-substring start end))
2495 nil))))
2496 prefix-length)
2497 (when (and prefix (null (string= prefix "")))
2498 (setq prefix-length (length prefix))
2499 (maphash (lambda (key val)
2500 (let ((key-name (symbol-name key)))
2501 (when (and (>= (length key-name) prefix-length)
2502 (string= prefix (substring key-name 0 prefix-length)))
2503 (push key-name collection))))
2504 ses--completion-table)
2505 (and collection (list start end collection))))))
2446 2506
2447(defun ses-edit-cell (row col newval) 2507(defun ses-edit-cell (row col newval)
2448 "Display current cell contents in minibuffer, for editing. Returns nil if 2508 "Display current cell contents in minibuffer, for editing. Returns nil if
@@ -2464,6 +2524,10 @@ cell formula was unsafe and user declined confirmation."
2464 (if (stringp formula) 2524 (if (stringp formula)
2465 ;; Position cursor inside close-quote. 2525 ;; Position cursor inside close-quote.
2466 (setq initial (cons initial (length initial)))) 2526 (setq initial (cons initial (length initial))))
2527 (dolist (key ses-completion-keys)
2528 (define-key ses-mode-edit-map key 'ses-edit-cell-complete-symbol))
2529 ;; make it globally visible, so that it can be visible from the minibuffer.
2530 (setq ses--completion-table ses--named-cell-hashmap)
2467 (list row col 2531 (list row col
2468 (read-from-minibuffer (format "Cell %s: " ses--curcell) 2532 (read-from-minibuffer (format "Cell %s: " ses--curcell)
2469 initial 2533 initial
@@ -2558,6 +2622,40 @@ cells."
2558;;---------------------------------------------------------------------------- 2622;;----------------------------------------------------------------------------
2559;; Input of cell-printer functions 2623;; Input of cell-printer functions
2560;;---------------------------------------------------------------------------- 2624;;----------------------------------------------------------------------------
2625(defun ses-read-printer-complete-symbol ()
2626 (interactive)
2627 (let ((completion-at-point-functions (cons 'ses--read-printer-completion-at-point-function
2628 completion-at-point-functions)))
2629 (completion-at-point)))
2630
2631(defun ses--read-printer-completion-at-point-function ()
2632 (let* ((bol (save-excursion (move-beginning-of-line nil) (point)))
2633 start end collection
2634 (prefix
2635 (save-excursion
2636 (setq end (point))
2637 (backward-sexp)
2638 (if (< (point) bol)
2639 (progn
2640 (setq start bol)
2641 (buffer-substring start end))
2642 (setq start (point))
2643 (forward-sexp)
2644 (if (>= (point) end)
2645 (progn
2646 (setq end (point))
2647 (buffer-substring start end))
2648 nil))))
2649 prefix-length)
2650 (when prefix
2651 (setq prefix-length (length prefix))
2652 (maphash (lambda (key val)
2653 (let ((key-name (symbol-name key)))
2654 (when (and (>= (length key-name) prefix-length)
2655 (string= prefix (substring key-name 0 prefix-length)))
2656 (push key-name collection))))
2657 ses--completion-table)
2658 (and collection (list start end collection)))))
2561 2659
2562(defun ses-read-printer (prompt default) 2660(defun ses-read-printer (prompt default)
2563 "Common code for functions `ses-read-cell-printer', `ses-read-column-printer', 2661 "Common code for functions `ses-read-cell-printer', `ses-read-column-printer',
@@ -2570,6 +2668,10 @@ canceled."
2570 (setq prompt (format "%s (default %S): " 2668 (setq prompt (format "%s (default %S): "
2571 (substring prompt 0 -2) 2669 (substring prompt 0 -2)
2572 default))) 2670 default)))
2671 (dolist (key ses-completion-keys)
2672 (define-key ses-mode-edit-map key 'ses-read-printer-complete-symbol))
2673 ;; make it globally visible, so that it can be visible from the minibuffer.
2674 (setq ses--completion-table ses--local-printer-hashmap)
2573 (let ((new (read-from-minibuffer prompt 2675 (let ((new (read-from-minibuffer prompt
2574 nil ; Initial contents. 2676 nil ; Initial contents.
2575 ses-mode-edit-map 2677 ses-mode-edit-map
@@ -3278,6 +3380,78 @@ is non-nil. Newlines and tabs in the export text are escaped."
3278 (setq result (apply #'concat (nreverse result))) 3380 (setq result (apply #'concat (nreverse result)))
3279 (kill-new result))) 3381 (kill-new result)))
3280 3382
3383;;----------------------------------------------------------------------------
3384;; Interactive help on symbols
3385;;----------------------------------------------------------------------------
3386
3387(defun ses-list-local-printers (&optional local-printer-hashmap)
3388 "List local printers in a help buffer. Can be called either
3389during editing a printer or a formula, or while in the SES
3390buffer."
3391 (interactive
3392 (list (cond
3393 ((derived-mode-p 'ses-mode) ses--local-printer-hashmap)
3394 ((minibufferp) ses--completion-table)
3395 ((derived-mode-p 'help-mode) nil)
3396 (t (error "Not in a SES buffer")))))
3397 (when local-printer-hashmap
3398 (let ((ses--list-orig-buffer (or ses--list-orig-buffer (current-buffer))))
3399 (help-setup-xref
3400 (list (lambda (local-printer-hashmap buffer)
3401 (let ((ses--list-orig-buffer
3402 (if (buffer-live-p buffer) buffer)))
3403 (ses-list-local-printers local-printer-hashmap)))
3404 local-printer-hashmap ses--list-orig-buffer)
3405 (called-interactively-p 'interactive))
3406
3407 (save-excursion
3408 (with-help-window (help-buffer)
3409 (if (= 0 (hash-table-count local-printer-hashmap))
3410 (princ "No local printers defined.")
3411 (princ "List of local printers definitions:\n")
3412 (maphash (lambda (key val)
3413 (princ key)
3414 (princ " as ")
3415 (prin1 (ses--locprn-def val))
3416 (princ "\n"))
3417 local-printer-hashmap))
3418 (with-current-buffer standard-output
3419 (buffer-string)))))))
3420
3421(defun ses-list-named-cells (&optional named-cell-hashmap)
3422 "List named cells in a help buffer. Can be called either
3423during editing a printer or a formula, or while in the SES
3424buffer."
3425 (interactive
3426 (list (cond
3427 ((derived-mode-p 'ses-mode) ses--named-cell-hashmap)
3428 ((minibufferp) ses--completion-table)
3429 ((derived-mode-p 'help-mode) nil)
3430 (t (error "Not in a SES buffer")))))
3431 (when named-cell-hashmap
3432 (let ((ses--list-orig-buffer (or ses--list-orig-buffer (current-buffer))))
3433 (help-setup-xref
3434 (list (lambda (named-cell-hashmap buffer)
3435 (let ((ses--list-orig-buffer
3436 (if (buffer-live-p buffer) buffer)))
3437 (ses-list-named-cells named-cell-hashmap)))
3438 named-cell-hashmap ses--list-orig-buffer)
3439 (called-interactively-p 'interactive))
3440
3441 (save-excursion
3442 (with-help-window (help-buffer)
3443 (if (= 0 (hash-table-count named-cell-hashmap))
3444 (princ "No cell was renamed.")
3445 (princ "List of named cells definitions:\n")
3446 (maphash (lambda (key val)
3447 (princ key)
3448 (princ " for ")
3449 (prin1 (ses-create-cell-symbol (car val) (cdr val)))
3450 (princ "\n"))
3451 named-cell-hashmap))
3452 (with-current-buffer standard-output
3453 (buffer-string)))))))
3454
3281 3455
3282;;---------------------------------------------------------------------------- 3456;;----------------------------------------------------------------------------
3283;; Other user commands 3457;; Other user commands
@@ -3460,8 +3634,12 @@ highlighted range in the spreadsheet."
3460 3634
3461(defun ses-replace-name-in-formula (formula old-name new-name) 3635(defun ses-replace-name-in-formula (formula old-name new-name)
3462 (let ((new-formula formula)) 3636 (let ((new-formula formula))
3463 (unless (and (consp formula) 3637 (cond
3464 (eq (car-safe formula) 'quote)) 3638 ((eq (car-safe formula) 'quote))
3639 ((symbolp formula)
3640 (if (eq formula old-name)
3641 (setq new-formula new-name)))
3642 ((consp formula)
3465 (while formula 3643 (while formula
3466 (let ((elt (car-safe formula))) 3644 (let ((elt (car-safe formula)))
3467 (cond 3645 (cond
@@ -3470,8 +3648,8 @@ highlighted range in the spreadsheet."
3470 ((and (symbolp elt) 3648 ((and (symbolp elt)
3471 (eq (car-safe formula) old-name)) 3649 (eq (car-safe formula) old-name))
3472 (setcar formula new-name)))) 3650 (setcar formula new-name))))
3473 (setq formula (cdr formula)))) 3651 (setq formula (cdr formula)))))
3474 new-formula)) 3652 new-formula))
3475 3653
3476(defun ses-rename-cell (new-name &optional cell) 3654(defun ses-rename-cell (new-name &optional cell)
3477 "Rename current cell." 3655 "Rename current cell."
@@ -3496,9 +3674,10 @@ highlighted range in the spreadsheet."
3496 (rowcol (ses-sym-rowcol sym)) 3674 (rowcol (ses-sym-rowcol sym))
3497 (row (car rowcol)) 3675 (row (car rowcol))
3498 (col (cdr rowcol)) 3676 (col (cdr rowcol))
3499 new-rowcol old-name) 3677 new-rowcol old-name old-value)
3500 (setq cell (or cell (ses-get-cell row col)) 3678 (setq cell (or cell (ses-get-cell row col))
3501 old-name (ses-cell-symbol cell) 3679 old-name (ses-cell-symbol cell)
3680 old-value (symbol-value old-name)
3502 new-rowcol (ses-decode-cell-symbol (symbol-name new-name))) 3681 new-rowcol (ses-decode-cell-symbol (symbol-name new-name)))
3503 ;; when ses-rename-cell is called interactively, then 'sym' is the 3682 ;; when ses-rename-cell is called interactively, then 'sym' is the
3504 ;; 'cursor-intangible' property of text at cursor position, while 3683 ;; 'cursor-intangible' property of text at cursor position, while
@@ -3518,10 +3697,12 @@ highlighted range in the spreadsheet."
3518 (put new-name 'ses-cell :ses-named) 3697 (put new-name 'ses-cell :ses-named)
3519 (puthash new-name rowcol ses--named-cell-hashmap)) 3698 (puthash new-name rowcol ses--named-cell-hashmap))
3520 (push `(ses-rename-cell ,old-name ,cell) buffer-undo-list) 3699 (push `(ses-rename-cell ,old-name ,cell) buffer-undo-list)
3700 (cl-pushnew rowcol ses--deferred-write :test #'equal)
3521 ;; Replace name by new name in formula of cells refering to renamed cell. 3701 ;; Replace name by new name in formula of cells refering to renamed cell.
3522 (dolist (ref (ses-cell-references cell)) 3702 (dolist (ref (ses-cell-references cell))
3523 (let* ((x (ses-sym-rowcol ref)) 3703 (let* ((x (ses-sym-rowcol ref))
3524 (xcell (ses-get-cell (car x) (cdr x)))) 3704 (xcell (ses-get-cell (car x) (cdr x))))
3705 (cl-pushnew x ses--deferred-write :test #'equal)
3525 (setf (ses-cell-formula xcell) 3706 (setf (ses-cell-formula xcell)
3526 (ses-replace-name-in-formula 3707 (ses-replace-name-in-formula
3527 (ses-cell-formula xcell) 3708 (ses-cell-formula xcell)
@@ -3532,11 +3713,14 @@ highlighted range in the spreadsheet."
3532 (dolist (ref (ses-formula-references (ses-cell-formula cell))) 3713 (dolist (ref (ses-formula-references (ses-cell-formula cell)))
3533 (let* ((x (ses-sym-rowcol ref)) 3714 (let* ((x (ses-sym-rowcol ref))
3534 (xcell (ses-get-cell (car x) (cdr x)))) 3715 (xcell (ses-get-cell (car x) (cdr x))))
3716 (cl-pushnew x ses--deferred-write :test #'equal)
3535 (setf (ses-cell-references xcell) 3717 (setf (ses-cell-references xcell)
3536 (cons new-name (delq old-name 3718 (cons new-name (delq old-name
3537 (ses-cell-references xcell)))))) 3719 (ses-cell-references xcell))))))
3538 (set (make-local-variable new-name) (symbol-value sym)) 3720 (set (make-local-variable new-name) (symbol-value sym))
3539 (setf (ses-cell--symbol cell) new-name) 3721 (setf (ses-cell--symbol cell) new-name)
3722 ;; set new name to value
3723 (set new-name old-value)
3540 ;; Unbind old name 3724 ;; Unbind old name
3541 (if (eq (get old-name 'ses-cell) :ses-named) 3725 (if (eq (get old-name 'ses-cell) :ses-named)
3542 (ses--unbind-cell-name old-name) 3726 (ses--unbind-cell-name old-name)
diff --git a/lisp/simple.el b/lisp/simple.el
index 1db14a859d6..3d23fc35596 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -5942,6 +5942,10 @@ columns by which window is scrolled from left margin.
5942When the `track-eol' feature is doing its job, the value is 5942When the `track-eol' feature is doing its job, the value is
5943`most-positive-fixnum'.") 5943`most-positive-fixnum'.")
5944 5944
5945(defvar last--line-number-width 0
5946 "Last value of width used for displaying line numbers.
5947Used internally by `line-move-visual'.")
5948
5945(defcustom line-move-ignore-invisible t 5949(defcustom line-move-ignore-invisible t
5946 "Non-nil means commands that move by lines ignore invisible newlines. 5950 "Non-nil means commands that move by lines ignore invisible newlines.
5947When this option is non-nil, \\[next-line], \\[previous-line], \\[move-end-of-line], and \\[move-beginning-of-line] behave 5951When this option is non-nil, \\[next-line], \\[previous-line], \\[move-end-of-line], and \\[move-beginning-of-line] behave
@@ -6212,6 +6216,7 @@ not vscroll."
6212If NOERROR, don't signal an error if we can't move that many lines." 6216If NOERROR, don't signal an error if we can't move that many lines."
6213 (let ((opoint (point)) 6217 (let ((opoint (point))
6214 (hscroll (window-hscroll)) 6218 (hscroll (window-hscroll))
6219 (lnum-width (line-number-display-width t))
6215 target-hscroll) 6220 target-hscroll)
6216 ;; Check if the previous command was a line-motion command, or if 6221 ;; Check if the previous command was a line-motion command, or if
6217 ;; we were called from some other command. 6222 ;; we were called from some other command.
@@ -6219,9 +6224,19 @@ If NOERROR, don't signal an error if we can't move that many lines."
6219 (memq last-command `(next-line previous-line ,this-command))) 6224 (memq last-command `(next-line previous-line ,this-command)))
6220 ;; If so, there's no need to reset `temporary-goal-column', 6225 ;; If so, there's no need to reset `temporary-goal-column',
6221 ;; but we may need to hscroll. 6226 ;; but we may need to hscroll.
6222 (if (or (/= (cdr temporary-goal-column) hscroll) 6227 (progn
6223 (> (cdr temporary-goal-column) 0)) 6228 (if (or (/= (cdr temporary-goal-column) hscroll)
6224 (setq target-hscroll (cdr temporary-goal-column))) 6229 (> (cdr temporary-goal-column) 0))
6230 (setq target-hscroll (cdr temporary-goal-column)))
6231 ;; Update the COLUMN part of temporary-goal-column if the
6232 ;; line-number display changed its width since the last
6233 ;; time.
6234 (setq temporary-goal-column
6235 (cons (+ (car temporary-goal-column)
6236 (/ (float (- lnum-width last--line-number-width))
6237 (frame-char-width)))
6238 (cdr temporary-goal-column)))
6239 (setq last--line-number-width lnum-width))
6225 ;; Otherwise, we should reset `temporary-goal-column'. 6240 ;; Otherwise, we should reset `temporary-goal-column'.
6226 (let ((posn (posn-at-point)) 6241 (let ((posn (posn-at-point))
6227 x-pos) 6242 x-pos)
diff --git a/lisp/startup.el b/lisp/startup.el
index bc60bbd08b8..0fbba1bea23 100644
--- a/lisp/startup.el
+++ b/lisp/startup.el
@@ -1432,6 +1432,7 @@ settings will be marked as \"CHANGED outside of Customize\"."
1432 (let ((no-vals '("no" "off" "false" "0")) 1432 (let ((no-vals '("no" "off" "false" "0"))
1433 (settings '(("menuBar" "MenuBar" menu-bar-mode nil) 1433 (settings '(("menuBar" "MenuBar" menu-bar-mode nil)
1434 ("toolBar" "ToolBar" tool-bar-mode nil) 1434 ("toolBar" "ToolBar" tool-bar-mode nil)
1435 ("scrollBar" "ScrollBar" scroll-bar-mode nil)
1435 ("cursorBlink" "CursorBlink" no-blinking-cursor t)))) 1436 ("cursorBlink" "CursorBlink" no-blinking-cursor t))))
1436 (dolist (x settings) 1437 (dolist (x settings)
1437 (if (member (x-get-resource (nth 0 x) (nth 1 x)) no-vals) 1438 (if (member (x-get-resource (nth 0 x) (nth 1 x)) no-vals)
diff --git a/lisp/subr.el b/lisp/subr.el
index a9edff6166f..79a28d301e7 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -725,15 +725,18 @@ Elements of ALIST that are not conses are ignored."
725 (setq tail tail-cdr)))) 725 (setq tail tail-cdr))))
726 alist) 726 alist)
727 727
728(defun alist-get (key alist &optional default remove) 728(defun alist-get (key alist &optional default remove testfn)
729 "Return the value associated with KEY in ALIST, using `assq'. 729 "Return the value associated with KEY in ALIST.
730If KEY is not found in ALIST, return DEFAULT. 730If KEY is not found in ALIST, return DEFAULT.
731Use TESTFN to lookup in the alist if non-nil. Otherwise, use `assq'.
731 732
732This is a generalized variable suitable for use with `setf'. 733This is a generalized variable suitable for use with `setf'.
733When using it to set a value, optional argument REMOVE non-nil 734When using it to set a value, optional argument REMOVE non-nil
734means to remove KEY from ALIST if the new value is `eql' to DEFAULT." 735means to remove KEY from ALIST if the new value is `eql' to DEFAULT."
735 (ignore remove) ;;Silence byte-compiler. 736 (ignore remove) ;;Silence byte-compiler.
736 (let ((x (assq key alist))) 737 (let ((x (if (not testfn)
738 (assq key alist)
739 (assoc key alist testfn))))
737 (if x (cdr x) default))) 740 (if x (cdr x) default)))
738 741
739(defun remove (elt seq) 742(defun remove (elt seq)
@@ -1786,7 +1789,8 @@ Return the new history list.
1786If MAXELT is non-nil, it specifies the maximum length of the history. 1789If MAXELT is non-nil, it specifies the maximum length of the history.
1787Otherwise, the maximum history length is the value of the `history-length' 1790Otherwise, the maximum history length is the value of the `history-length'
1788property on symbol HISTORY-VAR, if set, or the value of the `history-length' 1791property on symbol HISTORY-VAR, if set, or the value of the `history-length'
1789variable. 1792variable. The possible values of maximum length have the same meaning as
1793the values of `history-length'.
1790Remove duplicates of NEWELT if `history-delete-duplicates' is non-nil. 1794Remove duplicates of NEWELT if `history-delete-duplicates' is non-nil.
1791If optional fourth arg KEEP-ALL is non-nil, add NEWELT to history even 1795If optional fourth arg KEEP-ALL is non-nil, add NEWELT to history even
1792if it is empty or a duplicate." 1796if it is empty or a duplicate."
diff --git a/lisp/vc/vc-src.el b/lisp/vc/vc-src.el
index 5c8b3da6f1a..0e47cc1512f 100644
--- a/lisp/vc/vc-src.el
+++ b/lisp/vc/vc-src.el
@@ -180,7 +180,7 @@ For a description of possible values, see `vc-check-master-templates'."
180 180
181(defun vc-src-dir-status-files (dir files update-function) 181(defun vc-src-dir-status-files (dir files update-function)
182 ;; FIXME: Use one src status -a call for this 182 ;; FIXME: Use one src status -a call for this
183 (if (not files) (setq files (vc-expand-dirs (list dir) 'RCS))) 183 (if (not files) (setq files (vc-expand-dirs (list dir) 'SRC)))
184 (let ((result nil)) 184 (let ((result nil))
185 (dolist (file files) 185 (dolist (file files)
186 (let ((state (vc-state file)) 186 (let ((state (vc-state file))
diff --git a/lisp/wid-edit.el b/lisp/wid-edit.el
index ca402c18e53..6687bec31f6 100644
--- a/lisp/wid-edit.el
+++ b/lisp/wid-edit.el
@@ -3694,15 +3694,17 @@ example:
3694(defun widget-color--choose-action (widget &optional _event) 3694(defun widget-color--choose-action (widget &optional _event)
3695 (list-colors-display 3695 (list-colors-display
3696 nil nil 3696 nil nil
3697 `(lambda (color) 3697 (let ((cbuf (current-buffer))
3698 (when (buffer-live-p ,(current-buffer)) 3698 (wp (widget-get widget :parent)))
3699 (widget-value-set ',(widget-get widget :parent) color) 3699 (lambda (color)
3700 (let* ((buf (get-buffer "*Colors*")) 3700 (when (buffer-live-p cbuf)
3701 (win (get-buffer-window buf 0))) 3701 (widget-value-set wp color)
3702 (if win 3702 (let* ((buf (get-buffer "*Colors*"))
3703 (quit-window nil win) 3703 (win (get-buffer-window buf 0)))
3704 (bury-buffer buf))) 3704 (if win
3705 (pop-to-buffer ,(current-buffer)))))) 3705 (quit-window nil win)
3706 (bury-buffer buf)))
3707 (pop-to-buffer cbuf))))))
3706 3708
3707(defun widget-color-sample-face-get (widget) 3709(defun widget-color-sample-face-get (widget)
3708 (let* ((value (condition-case nil 3710 (let* ((value (condition-case nil
diff --git a/lisp/window.el b/lisp/window.el
index 43e9e995953..2b979f46636 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -7192,9 +7192,9 @@ See `display-buffer' for the format of display actions."
7192 (let ((pars (special-display-p (buffer-name buffer)))) 7192 (let ((pars (special-display-p (buffer-name buffer))))
7193 (when pars 7193 (when pars
7194 (list (list #'display-buffer-reuse-window 7194 (list (list #'display-buffer-reuse-window
7195 `(lambda (buffer _alist) 7195 (lambda (buffer _alist)
7196 (funcall special-display-function 7196 (funcall special-display-function
7197 buffer ',(if (listp pars) pars))))))))) 7197 buffer (if (listp pars) pars)))))))))
7198 7198
7199(defun display-buffer-pop-up-frame (buffer alist) 7199(defun display-buffer-pop-up-frame (buffer alist)
7200 "Display BUFFER in a new frame. 7200 "Display BUFFER in a new frame.